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!
");
    }
}
原文地址:https://www.cnblogs.com/sweat123/p/4948832.html