您的位置:首页 > 产品设计 > UI/UE

【POJ 1679 The Unique MST】最小生成树

2015-11-10 00:26 495 查看
无向连通图(无重边),判断最小生成树是否唯一,若唯一求边权和。

分析生成树的生成过程,只有一个圈内出现权值相同的边才会出现权值和相等但“异构”的生成树。(并不一定是最小生成树)

分析贪心策略求最小生成树的过程(贪心地选最短的边来扩充已加入生成树的顶点集合U),发现只有当出现“U中两个不同的点到V-U中同一点的距离同时为当前最短边”时,才会出现“异构”的最小生成树。

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int MAX_N=105;
const int MAX_M=5005;
const int INF=100000;
typedef pair<int,int> P;//cost,to
struct Edge
{
int to,cost;
Edge(){}
Edge(int tt,int cc):to(tt),cost(cc){}
};
int t;
int n,m;
vector<Edge> G[MAX_N];
int vis[MAX_N];
int mincost[MAX_N];

int prim()
{
int ans=0;
int flag=0;
priority_queue<P,vector<P>,greater<P> > que;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) mincost[i]=INF;
que.push(P(0,1));
mincost[1]=0;
while(!que.empty())
{
P p=que.top();
que.pop();
int v=p.second;
if(vis[v]||mincost[v]<p.first) continue;
vis[v]=1;
mincost[v]=p.first;
ans+=mincost[v];
for(int i=0;i<G[v].size();i++)
{
int u=G[v][i].to;
if(!vis[u])
{
if(mincost[u]>G[v][i].cost&&G[v][i].cost<INF)
{
mincost[u]=G[v][i].cost;
que.push(P(mincost[u],u));
}else if(mincost[u]==G[v][i].cost)//存在到达点u权值相等且都为最小值的边
{
flag=1;
break;
}
}
}
if(flag) break;
}
if(flag) ans=-1;
return ans;
}
int main()
{
freopen("1679.txt","r",stdin);
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) G[i].clear();
for(int i=0;i<m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
G[u].push_back(Edge(v,w));
G[v].push_back(Edge(u,w));
}
if(n==1) {printf("0\n"); continue;}
int ans=prim();
if(ans==-1)
printf("Not Unique!\n");
else printf("%d\n",ans);
}
return 0;
}


prim_priorityqueue
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: