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;
}
原文地址:https://www.cnblogs.com/Kurokey/p/5317578.html