【POJ 1679 The Unique MST】最小生成树
无向连通图(无重边),判断最小生成树是否唯一,若唯一求边权和。
分析生成树的生成过程,只有一个圈内出现权值相同的边才会出现权值和相等但“异构”的生成树。(并不一定是最小生成树)
分析贪心策略求最小生成树的过程(贪心地选最短的边来扩充已加入生成树的顶点集合U),发现只有当出现“U中两个不同的点到V-U中同一点的距离同时为当前最短边”时,才会出现“异构”的最小生成树。

上图为kruscal和prim生成过程中可能遇到的相等边的情况,红色和蓝色的为权值相等的边。
可以看到kruscal由于事先将所有边按权值排序,所以在构造MST的过程中,当发现权值相同的边时,需要遍历之前遇到过的所有相同权值的边来判断是否发生“争抢同一点”的情况,若发现即可判定存在“异构”最小生成树。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_N=;
const int MAX_M=; int par[MAX_N];
void init()
{
memset(par,-,sizeof(par));
}
int find(int x)
{
if(par[x]==-) return x;
return par[x]=find(par[x]);
}
void unite(int x,int y)
{
x=find(x);
y=find(y);
if(x!=y) par[x]=y;
}
bool same(int x,int y)
{
return find(x)==find(y);
} int t;
int n,m;
struct Edge
{
int u,v,w;
}e[MAX_M]; bool cmp(Edge e1,Edge e2)
{
return e1.w<e2.w;
} bool inter(Edge e1,Edge e2)
{
if(e1.u==e2.u||e1.u==e2.v||e1.v==e2.u||e1.v==e2.v) return true;
else return false;
} int kruscal()
{
int ans=;
init();
ans+=e[].w;
unite(e[].u,e[].v);
int cur_w=e[].w;
for(int i=;i<m;i++)
{
if(same(e[i].u,e[i].v))
{
for(int j=i-;e[j].w==e[i].w;j--)
{
if(inter(e[i],e[j]))//判两条边有无交点
{
ans=-;
break;
}
}
}else
{
unite(e[i].u,e[i].v);
ans+=e[i].w;
cur_w=e[i].w;
}
}
return ans;
} int main()
{
freopen("1679.txt","r",stdin);
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=;i<m;i++)
{
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
}
if(n==) {printf("0\n"); continue;}
sort(e,e+m,cmp);
int ans=kruscal();
if(ans==-)
printf("Not Unique!\n");
else printf("%d\n",ans);
}
return ;
}
kruscal
而prim由于每次都选连结U和V-U的边,所以不会遇到kruscal那样蓝色的可能误判的边(我开始就WA在这里),因此只需在加入一个新点更新其他点的mincost时判断有没有和mincost值相等的另一条边的即可。
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int MAX_N=;
const int MAX_M=;
const int INF=;
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=;
int flag=;
priority_queue<P,vector<P>,greater<P> > que;
memset(vis,,sizeof(vis));
for(int i=;i<=n;i++) mincost[i]=INF;
que.push(P(,));
mincost[]=;
while(!que.empty())
{
P p=que.top();
que.pop();
int v=p.second;
if(vis[v]||mincost[v]<p.first) continue;
vis[v]=;
mincost[v]=p.first;
ans+=mincost[v];
for(int i=;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=;
break;
}
}
}
if(flag) break;
}
if(flag) ans=-;
return ans;
}
int main()
{
freopen("1679.txt","r",stdin);
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) G[i].clear();
for(int i=;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==) {printf("0\n"); continue;}
int ans=prim();
if(ans==-)
printf("Not Unique!\n");
else printf("%d\n",ans);
}
return ;
}
prim_priorityqueue
【POJ 1679 The Unique MST】最小生成树的更多相关文章
- POJ 1679 The Unique MST (最小生成树)
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 22668 Accepted: 8038 D ...
- poj 1679 The Unique MST 【次小生成树】【模板】
题目:poj 1679 The Unique MST 题意:给你一颗树,让你求最小生成树和次小生成树值是否相等. 分析:这个题目关键在于求解次小生成树. 方法是,依次枚举不在最小生成树上的边,然后加入 ...
- poj 1679 The Unique MST(唯一的最小生成树)
http://poj.org/problem?id=1679 The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submis ...
- poj 1679 The Unique MST (判定最小生成树是否唯一)
题目链接:http://poj.org/problem?id=1679 The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total S ...
- poj 1679 The Unique MST
题目连接 http://poj.org/problem?id=1679 The Unique MST Description Given a connected undirected graph, t ...
- POJ 1679 The Unique MST (最小生成树)
The Unique MST 题目链接: http://acm.hust.edu.cn/vjudge/contest/124434#problem/J Description Given a conn ...
- POJ 1679 The Unique MST 【最小生成树/次小生成树模板】
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 22668 Accepted: 8038 D ...
- POJ 1679 The Unique MST 推断最小生成树是否唯一
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 22715 Accepted: 8055 D ...
- poj 1679 The Unique MST【次小生成树】
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 24034 Accepted: 8535 D ...
- POJ 1679 The Unique MST (次小生成树kruskal算法)
The Unique MST 时间限制: 10 Sec 内存限制: 128 MB提交: 25 解决: 10[提交][状态][讨论版] 题目描述 Given a connected undirect ...
随机推荐
- 【关于微软的上一代模板引擎 T4引擎】
导语:国内有名的动软代码生成器用的就是T4引擎......可以自己下载下来用用,批量生成固定模式的代码文件,十分有用........... 示例代码:示例代码__你必须懂的T4模板:浅入深出.rar ...
- MIT-scheme安装
下载地址: http://www.gnu.org/software/mit-scheme/ 下载windows版本,安装. The MIT-Scheme can be installed by jus ...
- UESTC_秋实大哥与小朋友 2015 UESTC Training for Data Structures<Problem A>
A - 秋实大哥与小朋友 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Sub ...
- curl 浏览器模拟请求实战
1,curl 常用选项
- (转)Java 的swing.GroupLayout布局管理器的使用方法和实例
摘自http://www.cnblogs.com/lionden/archive/2012/12/11/grouplayout.html (转)Java 的swing.GroupLayout布局管理器 ...
- 基于Vue 和 webpack的项目实现
Vue.js 是一款极简的 mvvm 框架,如果让我用一个词来形容它,就是 “轻·巧” .如果用一句话来描述它,它能够集众多优秀逐流的前端框架之大成,但同时保持简单易用.废话不多说,来看几个例子: & ...
- 【计算几何初步-线段相交+并查集】【HDU1558】Segment set
Segment set Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- [转载]android中The connection to adb is down,问题和解决
原网址:http://blog.sina.com.cn/s/blog_5fc93373010164p3.html 今天我出现了第3个错误,于是百度了一下.感觉这篇博客对我挺有帮助,推荐给大家.以下是原 ...
- 解决获取IP地址时出现“在一个非套…
今天单位的一台机器在用IPCONFIG/RENEW时遇到了这个问题,上网查了一下,网上的版本在对XP不太好用,网上的版本如下: 1.从注册表中备份以下项:(当然也可以用Erunt备份整个注册表)HKE ...
- 转载-SQL不同服务器数据库之间的数据操作整理(完整版) .
---------------------------------------------------------------------------------- -- Author : htl25 ...