Agri-Net 最短网络

农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。 约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。 你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。

Input

第一行: 农场的个数,N(3<=N<=100)。 第二行..结尾: 后来的行包含了一个N*N的矩阵,表示每个农场之间的距离。理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们限制在80个字符,因此,某些行会紧接着另一些行。当然,对角线将会是0,因为不会有线路从第i个农场到它本身。

Output

只有一个输出,其中包含连接到每个农场的光纤的最小长度。

Sample Input

4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0

Sample Output

28

kruskal  算法求解,(可能用prim会快一点,先占个坑)

开始时

#define N 105 写成了 #define N 100 + 5,还竟然是wrong answer?

#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <cstdio>
#include <vector>
#include <utility>
#include <cstring>
#include <iostream>
#include <algorithm>
#define eps 1e-8
#define PI acos(-1)
#define INF 0x3f3f3f3f
#define N 105
#define newmax(a,b) a>b?a:b
#define newmin(a,b) a>b?b:a
#define Lowbit(x) (x&-x)
using namespace std;
typedef long long int LL;
const int dir[4][2]= { {1,0},{0,1},{-1,0},{0,-1} };

struct Edge
{
    int s,e,v;
}edge[N*(N-1)/2];
int n,m;
int parent[N];

int cmp(struct Edge a,struct Edge b)
{
    return a.v<b.v;
}
void verset()
{
    for(int i=1;i<=n;i++)
        parent[i]=-1;
}

int Find(int x)
{
     int s;
     for(s=x;parent[s]>0;s=parent[s]);
     while(s!=x)
     {
         int temp=parent[x];
         parent[x]=s;
         x=temp;
     }
     return s;
}

void Union(int R1,int R2)
{
    int r1=Find(R1),r2=Find(R2);
    int temp=parent[r1]+parent[r2];
    if(parent[r2]<parent[r1])
    {
        parent[r1]=r2;
        parent[r2]=temp;
    }
    else{
        parent[r2]=r1;
        parent[r1]=temp;
    }
}

void Kruskal()
{
    int sum=0;
    int num=0;
    verset();
    for(int i=0;i<m;i++)
    {
        int u=edge[i].s,v=edge[i].e;
        if(Find(u)!=Find(v))
        {
            Union(u,v);
            num++;
            sum+=edge[i].v;
        }
        if(num>=n-1)
            break;
    }
    printf("%d\n",sum);
}
int main()
{
    int g=0;
    scanf("%d",&n);
    m=n*(n-1)/2;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            int t;
            scanf("%d",&t);
            if(i<j)
            {
                edge[g].v=t;
                edge[g].s=i;
                edge[g].e=j;
                g++;
            }
        }
    }
    sort(edge,edge+g,cmp);
    Kruskal();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/codertcm/article/details/82696211