洛谷 P1111 修复公路(最小生成树)
题目链接
https://www.luogu.org/problemnew/show/P1111
以后只发题目链接!!!
题目大意
给出A地区的村庄数N,和公路数M,公路是双向的。并告诉你每条公路的连着哪两个村庄,并告诉你什么时候能修完这条公路。问最早什么时候任意两个村庄能够通车,即最早什么时候任意两条村庄都存在至少一条修复完成的道路(可以由多条公路连成一条道路)
解题思路
很显然,求的是一个最小瓶颈生成树。我的另一篇博客:https://www.cnblogs.com/yinyuqin/p/10779387.html#index_6
所以,我们只需要跑一边最小生成树。这里用的是Kruskal算法。
我们要求的是最早的时间,所以我们只需用t存时间即可。题目中还说如果不连通输出-1,只需统计边数,是否=n-1即可。
建议大家看一看另外一道题,一个思路但解释得更详细:https://www.cnblogs.com/yinyuqin/p/10786887.html
还有一个很重要的一点:输入规模很大,用cin会爆掉!!!
十年oi一场空,一个cin见祖宗。
最后附上正解:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 using namespace std; 5 struct edge{ 6 int qidian; 7 int zhongdian; 8 int value; 9 }bian[100005]; 10 int n,m,fa[1005],t,cnt; 11 bool cmp(edge a,edge b){ 12 return a.value<b.value; 13 } 14 int find(int x){ 15 if(fa[x]==x)return x; 16 return fa[x]=find(fa[x]); 17 } 18 int main() 19 { 20 cin>>n>>m; 21 for(int i=1;i<=n;i++) fa[i]=i; 22 for(int i=1;i<=m;i++){ 23 scanf("%d%d%d",&bian[i].qidian,&bian[i].zhongdian,&bian[i].value); 24 } 25 sort(bian+1,bian+m+1,cmp); 26 for(int i=1;i<=m;i++){ 27 int p1=bian[i].qidian,p2=bian[i].zhongdian; 28 int f1=find(p1),f2=find(p2); 29 if(f1!=f2){ 30 cnt++; //统计已加入最小生成树的边数 31 t=bian[i].value; //t为时间(因为value是递增的,所以不同取max了) 32 fa[f1]=f2; 33 } 34 } 35 if(cnt!=n-1) cout<<-1; 36 else cout<<t; 37 return 0; 38 }