• 最小生成树


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

       
       
  • 相关阅读:
    ffmpeg
    HDU 1031 Design T-Shirt
    HDU 1029 Ignatius and the Princess IV
    HDU 1022 Train Problem I
    HDU 1017 A Mathematical Curiosity
    HDU 1015 Safecracker
    HDU 1002 A + B Problem II
    HDU 1070 Milk
    高精度算法(一)
    codeblocks 使用心得
  • 原文地址:https://www.cnblogs.com/zhangdashuai/p/3619622.html
Copyright © 2020-2023  润新知