码迷,mamicode.com
首页 > 其他好文 > 详细

POJ1679(判断是否为唯一MST)

时间:2019-09-20 21:10:56      阅读:57      评论:0      收藏:0      [点我收藏+]

标签:namespace   math   memset   inf   oid   访问   prim   ios   bsp   

//判断唯一MST的思想
//先用Prim算法求出最小生成树的值
//枚举MST体系外的每一条边,加入MST,必然形成一个环,判断u - v的
//权值边是否和u - v路径的最大权值边相等,如果相等,则存在不止一条MST
#include<iostream>//Judge 是否为唯一MST
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf (0x3f3f3f3f)
using namespace std;
const int maxn = 100 + 15;
int Grape[maxn][maxn];//u - v节点之间权值
int n,m;//节点数     边数
bool vis[maxn];
int p[maxn],d[maxn];
int maxLen[maxn][maxn];//u - v路径最长距离
int stack[maxn];//储存MST节点
void Prim()
{
    memset(vis,false,sizeof(vis));
    memset(p,-1,sizeof(p));
    memset(d,inf,sizeof(d));
    int top = 0;
    d[1] = 0;
    while(true)
    {
        int mincost = inf,u = 0;
        for(int i=1;i<=n;++i)
        {
            if(!vis[i]&&d[i]<mincost)//节点未被访问
            {
                mincost = d[i];
                u = i;
            }
        }//选取最小节点
        //更新和MST节点的maxLen
        vis[u] = true;
        if(mincost==inf)
            break;
        for(int v=0;v!=top;++v)// u 与 stack中
        {
            if(p[u]!=-1)
                maxLen[stack[v]][u] = maxLen[u][stack[v]] = max(maxLen[stack[v]][p[u]],mincost); 
        }//更新maxLen
        stack[top++] = u;//MST中加入节点
        //u -> 更新 v
        for(int v=1;v<=n;++v)
        {
            if(!vis[v]&&Grape[u][v]!=-1&&d[v]>Grape[u][v])
            {
                d[v] = Grape[u][v];
                p[v] = u;
            }
        }
    }
    int minn = inf;
    for(int u=1;u<=n;++u)
    {
        for(int v=1;v<=n;++v)
        {
            if(u!=v&&p[u]!=v&&p[v]!=u)//u v为体系外的边
                minn = min(minn,abs(Grape[u][v]-maxLen[u][v]));
        }
    }
    //cout<<minn<<endl;
    if(minn==0)
        cout<<"Not Unique!"<<endl;
    else{
        int sum = 0;
        for(int v=1;v<=n;++v)
            if(p[v]!=-1)
                sum += Grape[v][p[v]];
        cout<<sum<<endl;
    }
}
int main()
{
    int t;  cin>>t;
    while(t--)
    {
        memset(Grape,-1,sizeof(Grape));
        memset(maxLen,0,sizeof(maxLen));
        cin>>n>>m;
        int u,v,w;
        for(int i=0;i!=m;++i)
        {
            cin>>u>>v>>w;
            Grape[u][v] = Grape[v][u] = w;//如果u-v之间权值为-1则不存在边
        }//构图
        Prim();
    }
}

 

POJ1679(判断是否为唯一MST)

标签:namespace   math   memset   inf   oid   访问   prim   ios   bsp   

原文地址:https://www.cnblogs.com/newstartCY/p/11559432.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!