您的位置:首页 > 其它

[kuangbin带你飞]专题六 最小生成树 K POJ 1679

2016-10-20 18:15 435 查看
题目地址:https://vjudge.net/contest/66965#problem/K

思路:求最小生成树以及次小生成树,然后判断是否相同。

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=100+10;
int g[maxn][maxn],path[maxn][maxn];
int dist[maxn],pre[maxn],vis[maxn];
bool used[maxn][maxn];
int t,n,m,mst;

int prime()
{
int mst=0;
memset(path,0,sizeof(path));
memset(vis,0,sizeof(vis));
memset(used,0,sizeof(used));
vis[1]=1;
for(int i=1;i<=n;i++)
{
dist[i]=g[1][i];
pre[i]=1;
}
for(int i=2;i<=n;i++)
{
int u=-1;
for(int j=1;j<=n;j++)
{
if(!vis[j])
if(u==-1 || dist[j]<dist[u])
u=j;
}
used[u][pre[u]]=used[pre[u]][u]=true;
mst+=g[pre[u]][u];
vis[u]=1;
for(int j=1;j<=n;j++)
{
if(vis[j] && j!=u)
path[j][u]=path[u][j]=max(path[pre[u]][u],dist[u]);
if(!vis[j])
if(dist[j]>g[u][j])
{
dist[j]=g[u][j];
pre[j]=u;
}
}
}
return mst;
}

int second_tree()
{
int res=inf;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i==j)
continue;
if(!used[i][j])
res=min(res,mst-path[i][j]+g[i][j]);
}
return res;
}

int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
g[i][j]=inf;
for(int i=1;i<=m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
g[a][b]=g[b][a]=c;
}
mst=prime();
int sec=second_tree();
if(mst==sec)
printf("Not Unique!\n");
else
printf("%d\n",mst);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: