【sicily】 1090. Highways

// 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;
}
posted @ 2011-03-31 21:03  Harrison_  阅读(1077)  评论(0编辑  收藏  举报