标签:using turn can stdout i++ strong namespace while 部分
Kruskal算法
Kruskal算法是基于贪心的思想得到的。首先我们把所有的边按照权值先从小到大排列,接着按照顺序选取每条边,如果这条边的两个端点不属于同一集合,那么就将它们合并,直到所有的点都属于同一个集合为止。
http://cogs.pro/cogs/problem/problem.php?pid=7
/**************************************************************************************************** 最小生成树(Kruskal) ********************************************************************************************************/ #include<cstdio> #include<algorithm> using namespace std; struct Edge{ int from,to,dist; bool operator <(const Edge a)const{ return dist<a.dist; } }a[1200000]; int mFind[1550]; int Find(int x){//并查集 if(mFind[x]==x)return x; else mFind[x]=Find(mFind[x]); return mFind[x]; } int main(){ freopen("mcst.in","r",stdin); freopen("mcst.out","w",stdout); int n,x,a1=0;scanf("%d",&n); for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ scanf("%d",&x); if(x!=-1&&i<j)a[a1].from=i,a[a1].to=j,a[a1++].dist=x; } } for(int i=0;i<n;i++)mFind[i]=i; sort(a,a+a1);int j=0; //将所有边排序 int fa,fb,u,v,ans=0; for(int i=1;i<n;i++){//将连接两部分的最短边加入生成树 while(1){ u=a[j].from,v=a[j].to; fa=Find(u),fb=Find(v); if(fa!=fb){ ans+=a[j++].dist,mFind[fa]=fb; break; } j++; } } printf("%d",ans); return 0; }
标签:using turn can stdout i++ strong namespace while 部分
原文地址:http://www.cnblogs.com/bennettz/p/6863767.html