最小生成树--highway(poj 2485);

来源:互联网 发布:下载淘宝自动挂机软件 编辑:程序博客网 时间:2024/06/05 17:32

公路
时限:1000MS 内存限制:65536K
提交材料共计: 33392 接受: 15129
描述


这个岛国的Flatopia是完全平坦的。不幸的是,Flatopia没有公共公路。因此,在Flatopia的交通很困难。在政府意识到了这个问题。他们正计划修建一些公路,以便在没有离开公路系统的情况下在任何一对城镇之间开车。


Flatopian镇从1到n。每条公路连接两个城镇。所有的公路都是直线。所有公路都可以双向使用。公路可以自由交叉,但司机只能在公路之间的一个城镇,位于两条高速公路的尽头。


在政府希望将最长的公路长度减少到最低限度。然而,他们希望保证每个城镇都是高速公路-从其他城镇都可以到达。
输入


输入的第一行是一个整数t,它告诉接下来有多少个测试用例。
每个情况的第一行是整数n(3<=n<=500),这是村庄的数目。然后是n行,其中的i-th包含n个整数,而这些n个整数的j-是距离(距离应该是内[1,65536)的整数)。在村一和村j之间,每个测试用例后有一条空行。

输出


对于每个测试用例,您应该输出一个包含整数的行,这个整数是要构建的最长道路的长度,这样所有的村庄都连接起来,这个值是最小的。
样本输入


1


3
0 990 692
990 0 179
692 179 0
样本输出


692


提示
大量输入,建议使用scanf。


#include <iostream>#include <algorithm>#include <cstdio>#define NUM 510using namespace std;int n, m;       //顶点数和边数struct dot_line{    int u;    int v;    int w;}DL[NUM*NUM/2];//是一个结构体内东西:其中有 顶点坐标,两个定点之间的权值;int r[NUM*NUM/2];int set[NUM];int cmp(const int i, const int j) {    return DL[i].w<DL[j].w;}    //间接排序函数int find(int x) {//找出当前边两个端点所在集合编号    return set[x] == x ? x : set[x] = find(set[x]);}//并查集的findint Kruskal() {    int ans = 0;    for(int i = 0; i < n; i++)        set[i] = i; //初始化并查集    for(int i = 0; i < m; i++)        r[i] = i; //初始化边序号    sort(r, r+m, cmp); //给边排序    for(int i = 0; i < m; i++) {        int e = r[i];//表示依次取出边的值;(从小到大;)        int x = find(DL[e].u);        int y = find(DL[e].v);            //找出当前边两个端点所在集合编号        if(x != y) { ans = max(ans,DL[e].w); set[x] = y; } //如果在不同集合,合并    }    return ans;}int main(){    int T;    scanf("%d",&T);    while(T --){        scanf("%d",&n);        m = 0;//记录总的边数;        for(int i = 0;i < n;i ++)            for(int j = 0;j < n;j ++){                if(i<j){                    DL[m].u = i;                    DL[m].v = j;                    scanf("%d",&DL[m].w);                    m ++;                }                else{                    int kkkk;                    scanf("%d",&kkkk);                }            }        cout << Kruskal()<<endl;    }    return 0;}


方法二:


#include <iostream>#include <cstring>#include<cstdio>#define NUM 505using namespace std;int N;//村庄数int Graph[NUM][NUM];struct{    int adj;    int value;}G_V[NUM];int min_v(){    int i = 1;    while(!G_V[i].value&&i<=N)        i++;    int k  = i;    int min_ = G_V[k].value;    for(int j =1;j<=N;j++)        if(G_V[j].value<min_&&G_V[j].value>0)            {min_ = G_V[j].value;k = j;}    return k;}int K_r(){    int max_value = 0;    for(int i  = 1;i<=N;i++){        G_V[i].adj = 1;        G_V[i].value = Graph[1][i];    }    G_V[1].value = 0;    for(int i = 1;i<N;i++){        int k = min_v();        max_value = max(max_value,G_V[k].value);        G_V[k].value = 0;        for(int j = 1;j<=N;j++)            if(G_V[j].value>Graph[k][j]){                G_V[j].adj = k;                G_V[j].value = Graph[k][j];            }    }    return max_value;}int main(){    int caseNO;    scanf("%d",&caseNO);    while(caseNO--){        memset(Graph, 125, sizeof(Graph));        for(int i = 1;i<=NUM;i++)            {G_V[i].adj = 0;G_V[i].value = 1<<30;}            scanf("%d",&N);                for(int i = 1;i<=N;i++)            for(int j =1;j<=N;j++)                scanf("%d",&Graph[i][j]);        cout <<K_r()<<endl;    }    return 0;}




原创粉丝点击