hdu1233(floyd+并查集)

来源:互联网 发布:中国第一家网络银行 编辑:程序博客网 时间:2024/05/17 08:35

用最短距加并查集写出了最小树的效果

留个纪念吧~

#include <iostream>

using namespace std;

#define INF 10000

int a[1000][1000],n,d[INF];

int pre[105],sum;

void Init()

{

    for(int i=0;i<=150;i++)

    {

        for(int j=0;j<150;j++)

        {

            if(i==j)

                a[i][j]=0;

            else

                a[i][j]=INF;

        }

    }

}

void floyd()

{

    for(int k=1;k<=n;k++)

    {

        for(int i=1;i<=n;i++)

        {

            for(int j=1;j<=n;j++)

            {

                if(a[i][j]>a[i][k]+a[k][j])

                    a[i][j]=a[i][k]+a[k][j];

            }

        }

    }

}

int find(int x)

{

    int r=x;

    while(pre[r]!=r)

        r=pre[r];

    int i=x,j;

    while(pre[i]!=r)

    {

        j=pre[i];

        pre[i]=r;

        i=j;

    }

    return r;

}

void mix(int x,int y)

{

    int r=find(x);

    int l=find(y);

    if(l!=r)

        pre[l]=r;

}

void insert()

{

    while(1)

    {

        int min=100000,ii,jj,c,b;

        int flag=0;

        for(int i=1;i<=n;i++)

        {

            for(int j=i+1;j<=n;j++)

            {

                if(min>a[i][j])

                {

                    c=find(i);

                    b=find(j);

                    

                    if(c!=b)

                    {

                        ii=i;

                        jj=j;

                        min=a[i][j];

                        flag=1;

                    }

                }

            }

        }

        

        if(flag==0)

            break;

        c=find(ii);

        b=find(jj);

        //printf("%d->%d %d->%d\n",ii,c,jj,b);

        sum+=min;

        mix(ii,jj);

        a[ii][jj]=100005;

    }

    

}

int main()

{

    int i,j,w;

    while(~scanf("%d",&n)&&n!=0)

    {

        Init();

        int m=n*(n-1)/2;

        for(int k=0;k<m;k++)

        {

            scanf("%d %d %d",&i,&j,&w);

            a[i][j]=a[j][i]=w;

        }

        floyd();

        for(int i=1;i<=n;i++)

            pre[i]=i;

        sum=0;

        insert();

        cout<<sum<<endl;

        /*for(i=1;i<=n;i++)

        {

            for(j=1;j<=n;j++)

                printf("%d ",a[i][j]);

            printf("\n");

        }*/

    }

    return0;

}