标签:UVa10842 连通 return int 题解 Kruskal father edge find
最小大生成树。
这题几乎就是模板。看我翻译:
一个城市由N个节点,M条带权无向边组成。城市连通。由于公路养护部门预算不足,需要在城市连通的情况下关闭尽可能多的道路,且使剩余权值最小的道路权值尽可能大。求出这个权值。
因为图要连通,边要最少且边权尽量大,显然我们将要得到的是图的最大生成树。用Kruskal好求。
Kruskal通过将边排序,借助并查集判断当前边是否多余(不能有环)来尽量把更小(大)的边放入生成树。还有一种算法叫Prim求生成树。
代码:
#include<bits/stdc++.h>
using namespace std;
struct node
{
int a,b,d;
}edge[20000];
bool cmp(node x,node y)
{
return x.d>y.d;
}
int n,m,father[6000],ans,num;
int find(int x)//寻找祖先
{
if(father[x]-x)
father[x]=find(father[x]);
return father[x];
}
void pt(int x,int y)//合并
{
x=find(x);
y=find(y);
father[y]=x;
}
bool check(int x,int y)//判断是否连通
{
x=find(x);
y=find(y);
if(x==y)
return 1;
else
return 0;
}
int main()
{
int t;
cin>>t;
for(int f=1;f<=t;f++)
{
cin>>n>>m;
for(int i=1;i<=n;i++)
father[i]=i;
for(int i=1;i<=m;i++)
{
int x,y,w;
cin>>x>>y>>w;
edge[i].a=x;
edge[i].b=y;
edge[i].d=w;
}//建图,不需要邻接矩阵或邻接表,这样就行了,也好排序
sort(edge+1,edge+1+m,cmp);//排序
for(int i=1;i<=m;i++)
if(find(edge[i].a)-find(edge[i].b))//并查集操作
{
pt(edge[i].a,edge[i].b);//连通
ans=edge[i].d;//由于已经排序,边长单减,后加的边必定更小,因此直接更新答案。
num++;
if(num==n-1)//对于树,边数为点数减1
break;
}
printf("Case #%d: %d\n",f,ans);
num=ans=0;//输出答案后记得清0
}
return 0;
}
标签:UVa10842,连通,return,int,题解,Kruskal,father,edge,find 来源: https://www.cnblogs.com/s-t-a-r-d-u-s-t/p/11436843.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。