标签:
http://poj.org/problem?id=1679
Description
Input
Output
Sample Input
2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2
Sample Output
3 Not Unique!
/**
poj 1679 次小生成树
题目大意:给定一个无向图,问它的最小生成树是否唯一
解题思路:利用prim算法求出最小生成树,并且用mlen数组标记在已知的生成树上i和j两点之间的经过边的最大权值,最后枚举所有没有在最小生成树上的
边,加上该边,并且减去对应mlen,得到的结果就是必须用当前边的最小生成树,所有之中最小的就是次小生成树的大小,和最小生成树进行比较即可
*/
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
const int maxn=1010;
struct note
{
int x,y,z;
}p[maxn];
int a[maxn][maxn],dis[maxn];
int pre[maxn],n,m;
int flag[maxn][maxn],vis[maxn];
int mlen[maxn][maxn];
int prim(int u)
{
int sum=0;
memset(flag,0,sizeof(flag));
memset(vis,0,sizeof(vis));
memset(mlen,0,sizeof(mlen));
for(int i=1; i<=n; i++)
{
dis[i]=a[u][i];
pre[i]=u;
}
vis[u]=1;
for(int i=1; i<n; i++)
{
int minn=0x3f3f3f3f;
int v=-1;
for(int j=1; j<=n; j++)
{
if(!vis[j]&&dis[j]<minn)
{
v=j;
minn=dis[j];
}
}
if(v!=-1)
{
sum+=dis[v];
flag[v][pre[v]]=flag[pre[v]][v]=1;
vis[v]=1;
for(int k=1; k<=n; k++)
{
if(vis[k]&&k!=v)
{
mlen[v][k]=mlen[k][v]=max(mlen[k][pre[v]],dis[v]);
}
if(!vis[k]&&a[v][k]<dis[k])
{
dis[k]=a[v][k];
pre[k]=v;
}
}
}
}
return sum;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)
a[i][j]=0;
else
a[i][j]=0x3f3f3f3f;
}
}
for(int i=1; i<=m; i++)
{
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
a[x][y]=a[y][x]=w;
}
int ans=prim(1);
int cnt=0x3f3f3f3f;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(a[i][j]!=0x3f3f3f3f&&!flag[i][j])
{
cnt=min(cnt,ans-mlen[i][j]+a[i][j]);
}
}
}
if(cnt!=ans)
printf("%d\n",ans);
else
puts("Not Unique!");
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/46860587