• POJ1679(次小生成树)


    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17124

    题目描述:就是求次小生成树,若次小生成树与最小生成树相等则输出    Not Unique!   否则输出最小生成树权值和。

    题目思路:就是运用次小生成树算法

    AC代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #include <stack>
    #include <queue>
    #include <string>
    #include <vector>
    #include <set>
    #include <map>
    #include <climits>
    #define lson root<<1,l,mid
    #define rson root<<1|1,mid+1,r
    #define fi first
    #define se second
    #define ping(x,y) ((x-y)*(x-y))
    using namespace std;
    #define gamma 0.5772156649015328606065120 //欧拉常数
    #define MOD 1000000007
    #define inf 0x3f3f3f3f
    #define N 100001
    #define maxn 1000100
    typedef long long LL;
    typedef pair<int,int> PII;
    
    int pic[101][101],tans,used[101][101],path[101][101],n;
    ///used数组判断两点之间直接相连的边是否使用过,path数组记录最小生成树中点i到点j最大的边权值
    int prim()
    {
        int i,j,d[101],vis[101],ans=0,pre[101]; ///pre数组记录父节点
        memset(vis,0,sizeof(vis));
        memset(path,0,sizeof(path));
        for(i=0; i<n; ++i)
            d[i]=pic[0][i],pre[i]=0;
        vis[0]=1;
        for(i=1; i<n; ++i)
        {
            int m=inf,u;
            for(j=1; j<n; ++j)
                if(!vis[j]&&d[j]<m)
                    m=d[u=j];
            vis[u]=1;
            used[u][pre[u]]=used[pre[u]][u]=1;
            ans+=m;
            for(j=1; j<n; ++j)
            {
                if(vis[j])
                {
                    path[j][u]=path[u][j]=max(d[u],path[j][pre[u]]);   ///比较过程d[u]是生成树到u的值,path[j][pre[u]]是连接u点的父节点到j的权值
                }                                ///path数组更新过程类似DP过程
                if(!vis[j]&&d[j]>pic[u][j])
                {
                    d[j]=pic[u][j];
                    pre[j]=u;
                }
            }
        }
        return ans;
    }
    
    int t_prim(int &v)
    {
        int i,j,ans=inf;
        for(i=0; i<n; ++i)
            for(j=i+1; j<n; ++j)
            {
                if(!used[i][j])
                    ans=min(v+pic[i][j]-path[i][j],ans);
            }
        return ans;
    }
    
    int main()
    {
        int pos,group,x,y,v,Case=0;
        int i,j,m,_ans,k;
        scanf("%d",&group);
        while(group--)
        {
            scanf("%d%d",&n,&m);
            memset(pic,inf,sizeof(pic));
            memset(used,0,sizeof(used));
            for(i=0; i<m; ++i)
            {
                scanf("%d%d%d",&x,&y,&v);
                pic[x-1][y-1]=pic[y-1][x-1]=v;
            }
            _ans=prim();
            tans=t_prim(_ans);
            if(tans==_ans) printf("Not Unique!
    ");
            else printf("%d
    ",_ans);
    
        }
        return 0;
    }
  • 相关阅读:
    抽象类和接口的区别
    Overload和Override的区别
    final和finally和finalize的区别
    C#设计模式学习笔记:简单工厂模式(工厂方法模式前奏篇)
    C#设计模式学习笔记:(1)单例模式
    C#设计模式学习笔记:设计原则
    C#加密与解密(DESRSA)学习笔记
    C# IO流与文件读写学习笔记
    C#序列化与反序列化学习笔记
    C#索引器学习笔记
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5317578.html
Copyright © 2020-2023  润新知