您的位置:首页 > 其它

[kuangbin带你飞]专题八 生成树 A

2017-03-31 19:35 267 查看
题目地址:https://vjudge.net/contest/67265#problem/A

思路:次小生成树

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 105;
int n,m;
int ans;
int g[maxn][maxn];
bool vis[maxn];
bool used[maxn][maxn];
int Max[maxn][maxn];
int low[maxn];
int pre[maxn];
int prime()
{
int ans=0;
memset(vis,false,sizeof(vis));
memset(Max,0,sizeof(Max));
memset(used,false,sizeof(used));
vis[1]=true;
pre[1]=-1;
for(int i=2;i<=n;i++)
{
pre[i]=1;
low[i]=g[i][1];
}
low[1]=0;
for(int i=1;i<n;i++)
{
int minc=INF;
int p=-1;
for(int j=1;j<=n;j++)
{
if(!vis[j] && minc>low[j])
{
minc=low[j];
p=j;
}
}
if(minc==INF)
return -1;
ans+=minc;
vis[p]=true;
used[p][pre[p]]=used[pre[p]][p]=true;
for(int j=1;j<=n;j++)
{
if(vis[j])
Max[j][p]=Max[p][j]=max(Max[j][pre[p]],low[p]);
if(!vis[j] && low[j]>g[j][p])
{
low[j]=g[j][p];
pre[j]=p;
}
}
}
return ans;
}

int smst()
{
int Min=INF;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(g[i][j]!=INF && !used[i][j])
{
Min=min(Min,ans+g[i][j]-Max[i][j]);
}
if(Min==INF)return -1;//不存在
return Min;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
{
if(i!=j)
g[i][j]=INF;
else
g[i][j]=0;
}
for(int i = 0;i < m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
g[u][v]=g[v][u]=w;
}
ans=prime();
if(ans==-1)
{
printf("Not Unique!\n");
continue;
}
if(ans==smst())printf("Not Unique!\n");
else printf("%d\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: