【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;

}

你可能感兴趣的:(CI)