• poj1679 次小生成树


    prim方法:先求过一遍prim,同时标记使用过得边。然后同时记录任意2点间的最大值。

    每次加入一条新的边,会产生环,删去环中的最大值即可。

    #include<stdio.h>
    #include<string.h>
    #define INF 99999999
    const int maxn = 110;
    int map[maxn][maxn],vis[maxn],dis[maxn],n,pre[maxn],m,used[maxn][maxn];
    int maxd[maxn][maxn];
    int max(int x,int y){return x>y?x:y;}
    int min(int x,int y){return x<y?x:y;}
    void init()
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(i==j)map[i][j]=0;
                else map[i][j]=INF;
            }
        }
    }
    int prim()
    {
        int ans=0;
        int i,j,pos;
        memset(maxd,0,sizeof(maxd));
        for(i=1;i<=n;i++)
        {
            dis[i]=map[1][i];
            vis[i]=0;
            pre[i]=1;
        }
        vis[1]=1;
        pre[1]=-1;
        for(i=1;i<n;i++)
        {
            int minc=INF;
            for(j=1;j<=n;j++)
            {
                if(!vis[j]&&minc>dis[j])
                {
                    pos=j;
                    minc=dis[j];
                }
            }
            vis[pos]=1;
            ans+=minc;
            used[pre[pos]][pos]=used[pos][pre[pos]]=1;
            for(j=1;j<=n;j++)
            {
                if(vis[j])
                    maxd[pos][j]=maxd[j][pos]=max(maxd[j][pre[pos]],dis[pos]);
            }
            for(j=1;j<=n;j++)
            {
                if(!vis[j]&&dis[j]>map[pos][j])
                {
                    dis[j]=map[pos][j];
                    pre[j]=pos;
                }
            }
        }
        return ans;
    }
    int dfs(int x)
    {
        int ans=INF;
        int i,j;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if(i==j)continue;
                if(map[i][j]!=INF&&!used[i][j])
                {
                    ans=min(ans,x+map[i][j]-maxd[i][j]);
                }
            }
        }
        return ans;
    }
    int main()
    {
        int i,j,t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            init();
            for(i=0;i<m;i++)
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                if(map[x][y]>z)
                map[x][y]=map[y][x]=z;
            }
    
            memset(used,0,sizeof(used));
            int mst=prim();
            int second_mst=dfs(mst);
            if(second_mst!=mst)
                printf("%d
    ",mst);
            else printf("Not Unique!
    ");
        }
    }
  • 相关阅读:
    491 · 回文数
    936 · 首字母大写
    1343 · 两字符串和
    1535 · 转换成小写字母
    13 · 字符串查找
    146 · 大小写转换 II
    241 · 转换字符串到整数(容易版)
    46 · 主元素
    kotlin协程——>通道
    kotlin协程——>异步流
  • 原文地址:https://www.cnblogs.com/sweat123/p/4948832.html
Copyright © 2020-2023  润新知