zoukankan      html  css  js  c++  java
  • 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!
    ");
        }
    }
  • 相关阅读:
    OAF 开发,给组件添加javascript事件
    SQL SERVER占用CPU过高优化
    Winform嵌入CEF(非正常用法)
    多线程——i++的坑
    20150819(i++与++i的思考)
    listView中,checkBox的显示和隐藏
    装箱和拆箱
    虚方法
    [转]关于struct的一些解释与class对比
    提取行政区边界经纬度坐标(高德+百度)
  • 原文地址:https://www.cnblogs.com/sweat123/p/4948832.html
Copyright © 2011-2022 走看看