最小生成树

hdu 1102
题意:n个点 给出各点之间的距离,并且有的点之间已经有联系,求让所有的点联系最短的路径(最小生成树);
Kruskal算法特点是不断的选取最短的边 并且各边不能形成环 直到 生成树(并茶几为1);
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct Edge
{
    int u,v,w;
}edge[11111];
int map[111][111];
int n;
int fa[111];
bool cmp(Edge a,Edge b)
{
    if(a.w<b.w)
        return true;
    return false;
}
int find(int x)
{
    int y=x;
    while(fa[y]!=y)
    {
        y=fa[y];
    }
    return y;
}
void un(int x,int y)
{
    x=find(x),y=find(y);
    fa[x]=y;
    return ;
}
bool f()
{
    int sum=0,i;
    for(i=1;i<=n;i++)
        if(fa[i]==i)
            sum++;
    if(sum==1)
        return true;
    return false;
}
void Kruskal(int e)
{
    int sumweight=0;
    int i;
    int u,v;
    for(i=0;i<e;i++)
    {
        if(f())//判断此树是否生成
            break;
        u=find(edge[i].u),v=find(edge[i].v);
        if(map[edge[i].u][edge[i].v])
            continue;
        map[edge[i].u][edge[i].v]=1;
        map[edge[i].v][edge[i].u]=1;
        if(u==v)
            continue;
        un(edge[i].u,edge[i].v);//合并两点
        sumweight+=edge[i].w;//累加权值
    }
    cout<<sumweight<<endl;
    return ;
}
int main()
{
    int w,k,i,j;
    int x,c;
    while(cin>>n)
    {
        k=0;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
                cin>>map[i][j];
        }
        for(i=1;i<=n;i++)
            for(j=i+1;j<=n;j++)
            {
                if(i==j)
                    continue;
                if(map[i][j]==map[j][i])
                {
                    edge[k].u=i;edge[k].v=j;edge[k++].w=map[i][j];
                    continue;
                }
                else
                {
                   edge[k].u=i;edge[k].v=j;edge[k++].w=map[i][j];
                   edge[k].u=j;edge[k].v=i;edge[k++].w=map[j][i];
                }
            }
        for(i=1;i<=n;i++)
            fa[i]=i;
        memset(map,0,sizeof(map));
        cin>>x;
        c=x;
        while(x--)
        {
            cin>>i>>j;
            un(i,j);
            map[i][j]=map[j][i]=1;
        }
        sort(edge,edge+k,cmp);
        Kruskal(k);
    }
    return 0;
}

   
   
posted @ 2014-03-23 21:15  _一千零一夜  阅读(197)  评论(0编辑  收藏  举报