标签:ring for find div clu i++ std namespace 数据
//最小生成树模板 /* kruskal算法,把所有的边从小到大排序,接下来从小到大考查每条边(u,v); 1.u和v在同一个连通分量中,那么加入(u,v)后会形成环,因此不能选择。 2.如果u和v在不同的联通分量中,那么加入(u,v)一定是最优的。 */ #include<iostream> #include<cstring> #include<algorithm> using namespace std; int fat[102];//存放父节点 struct Lu { int u,v,w; }; bool cmp(Lu x,Lu y) {return x.w<y.w;}//排序函数 int find(int x) {return fat[x]==x?x:find(fat[x]);}//并查集,找根节点 int main() { for(int i=0;i<=100;i++)//初始化并查集 fat[i]=i; sort(L,L+k,cmp);//给边排序 for(int i=0;i<k;i++) { int x=find(L[i].u),y=find(L[i].v); if(x!=y) //不在同一个并查集,合并 { fat[y]=x; sum+=L[i].w;//权值加 } } return 0; } ************************************************************************ /* prim算法,任选一点s放到S集合中,从不在S集合中的点中选出一个点j使得其与S中的某点i的距离最短, 则(i,j)就是生成树的一条边,加入S中。继续按照上面找。数据量较大时用prim方便。 */ //prim 模板。这题数据太大用cruscal会超时。 #include<iostream> #include<cstdio> #include<cstring> int dis[502],map[502][502],mark[502]; const int MAX=10000007; int prim(int n) { for(int i=1;i<=n;i++) //初始化每个点到生成树中点的距离 { dis[i]=map[1][i]; mark[i]=0; } mark[1]=1; //1这个点加入生成树中。 int sum=0; for(int i=1;i<n;i++) //枚举n-1条边 { int sta=-1,Min=MAX; for(int j=1;j<=n;j++) //找不在生成树中的点中距离生成树中的点长度最小的 { if(!mark[j]&&dis[j]<Min) { Min=dis[j]; sta=j; } } if(sta==-1) return -1; //没找到可以可以联通的路 mark[sta]=1; //新找到的点加入生成树 sum+=Min; for(int j=1;j<=n;j++) //更新树外的点到树中的点的距离 { if(!mark[j]&&dis[j]>map[sta][j]) dis[j]=map[sta][j]; } } return sum; } int main() { return 0; }
标签:ring for find div clu i++ std namespace 数据
原文地址:http://www.cnblogs.com/--ZHIYUAN/p/6286071.html