这道题思路是最短路+二分 感觉难度应该在cf div2 的 b c左右吧
以长度为二分标准 每段路中 长度大于L的设为1 反之为0
然后就可通过dis[n]的大小 是否大于k来判断是否满足以L为免费最长路,之后的都可以交给电信公司处理
这里用了堆优化的dijkstra写
附上代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb push_back 4 #define mp make_pair 5 #define inf 0x3f3f3f3f 6 const int N=2e5+5; 7 int dis[N],vis[N],head[N],cnt; 8 int n,m,k; 9 struct ee{ 10 int from,to,next,len; 11 }e[N]; 12 void add(int u,int v,int l){ 13 cnt++; 14 e[cnt].from=u; 15 e[cnt].to=v; 16 e[cnt].len=l; 17 e[cnt].next=head[u]; 18 head[u]=cnt; 19 } 20 void dijkstra(int s,int ll){ 21 priority_queue<pair<int,int> >p; 22 for(int i=1;i<=n;i++){ 23 vis[i]=0; 24 dis[i]=inf; 25 } 26 dis[s]=0; 27 p.push(mp(0,s)); 28 while(!p.empty()){ 29 int u=p.top().second; 30 p.pop(); 31 if(vis[u])continue; 32 vis[u]=1; 33 for(int i=head[u];i;i=e[i].next){ 34 int j=e[i].to; 35 int k=e[i].len>ll?1:0; 36 if(dis[j]>dis[u]+k){ 37 dis[j]=dis[u]+k; 38 p.push(mp(-dis[j],j)); 39 } 40 } 41 } 42 } 43 int main(){ 44 cin>>n>>m>>k; 45 int u,v,l; 46 for(int i=1;i<=m;i++){ 47 cin>>u>>v>>l; 48 add(u,v,l); 49 add(v,u,l); 50 } 51 int left=0,right=1000002; 52 int ans=-1; 53 while(left<=right){ 54 int mid=(left+right)/2; 55 dijkstra(1,mid); 56 if(dis[n]>k){ 57 left=mid+1; 58 continue; 59 } 60 ans=mid; 61 right=mid-1; 62 } 63 printf("%d\n",ans); 64 }