【sicily】 1090. Highways
时间:2011-03-31 来源:Harrison_
// source code of submission 542687, Zhongshan University Online Judge System //经典的最小生成树算法(基于并查集)首先,要对所有边按权从小到大排序, //其次,要淘汰一些边,即使它们的权很小,但在生成树中它们是多余的(即构成环), //这里我们可以用并查集来解决。每选取一条边,我们就把这条边的两个顶点放进同一个连通分量 //通过一个能够寻找连通分量根结点的函数find(v)来判断。如果find(v1)==find(v2),那么v1和v2 //已经属于同一连通分量,那么v1与v2间的边就不能再添加到生成树中。第三,什么时候结束算法呢? //可以设置一个计数器,当已经添加了n-1条边时,生成树就构造好了。 #include <iostream> #include <algorithm> #include <stdio.h> using namespace std; struct Node{ int beg,end,dis; bool operator < (const Node &y) const{ return dis<y.dis; } }; int N,d,index,m,ans; Node edge[500*499/2]; int par[501]; int find(int x){ if (x == par[x]) return x; else{ par[x] = find(par[x]); return par[x]; } } int main(){ int T; scanf("%d",&T); while (T--){ index = 0; scanf("%d",&N); for (int i=0;i<N;i++){ for (int j=0;j<N;++j){ scanf("%d",&d); if (j>i){ edge[index].beg = i; edge[index].end = j; edge[index].dis = d; index ++; } } } sort(edge,edge+index); m = 0; ans = 0; for (int i=0;i<N;i++) par[i] = i; for (int i=0;i<index;++i){ if ( find(edge[i].beg) != find(edge[i].end)){ m++; ans = edge[i].dis; par[find(edge[i].beg)] = par[find(edge[i].end)]; if (m == N-1) break; } } printf("%d\n",ans); if (T!=0) printf("\n"); } return 0; }
相关阅读 更多 +