洛谷P1396 营救
题目链接:https://www.luogu.com.cn/problem/P1396
不太寻常的生成树问题,
这个题可以理解为最短路跑图,也可以理解为最小生成树找起点和终点的集合问题,
此题的解法多种,常见的是:dijkstra,kruskal,kruskal重构树问题,树上问题求解,二分并查集求解,当然
最简单的还是纯kruskal;
但这个题不完全是kruskal,因为这个题要求给出拥挤度的最小
"所以请你帮她规划一条从 s 至 t 的路线,使得经过道路的拥挤度最大值最小"。
什么意思呢,当然,这个题可不是求生成树的值哈;
这个题是从头开始跑,判断起点s和终点t是否联通,如果联通了就立马输出当前的权值,这个时候的拥挤度就是最小的,因为
1.满足了条件,从s可以到t;
2.最小生成树按边权值排序了,从小取到大,这时候输出必定是最小的。
当然,这个题用最短路跑是一点问题都没有的,尤其是用dijkstra。
spfa的话我就不确定了。
然后这个题按MST跑图,联通了输出就🆗了;
再次嘱咐:
不是求MST,
不是求MST,
不是求MST
Talk is cheap. Show me the code.
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m; 4 const int num=1e5+10; 5 struct edge 6 { 7 int u; 8 int v; 9 int w; 10 }e[num]; 11 int ans; 12 int st,t; 13 int s[num]; 14 bool cmp(edge a,edge b) 15 { 16 return a.w<b.w; 17 } 18 int find_set(int x) 19 { 20 if(x!=s[x]) 21 { 22 s[x]=find_set(s[x]); 23 } 24 return s[x]; 25 } 26 void kruskal() 27 { 28 for(register int i=1;i<=n;i++) 29 { 30 s[i]=i; 31 } 32 sort(e+1,e+1+m,cmp); 33 for(register int i=1;i<=m;i++) 34 { 35 int b=find_set(e[i].u); 36 int c=find_set(e[i].v); 37 if(b==c) 38 { 39 continue; 40 } 41 s[c]=b; 42 ans+=e[i].w; 43 if(find_set(st)==find_set(t))//首次联通直接输出即可 44 { 45 cout<<e[i].w<<endl; 46 break; 47 } 48 }//这里不必在进行cnt判断,这不是判断最小生成树的不连通性 49 } 50 int main() 51 { 52 std::ios::sync_with_stdio(false); 53 cin>>n>>m>>st>>t; 54 for(register int i=1;i<=m;i++) 55 { 56 cin>>e[i].u>>e[i].v>>e[i].w; 57 } 58 kruskal(); 59 return 0; 60 }
本文来自博客园,作者:江上舟摇,转载请注明原文链接:https://www.cnblogs.com/LQS-blog/p/16210404.html