【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 ...
随机推荐
- cf478A Initial Bet
A. Initial Bet time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- LeeCode-Linked List Cycle
Given a linked list, determine if it has a cycle in it. /** * Definition for singly-linked list. * s ...
- Python 自动化脚本学习(二)
流程控制 布尔值 temp = True temp = False 比较符号 == != < <= > >= 与或非 and or not 混合布尔的比较 (4<5)an ...
- SHDP--Working with HBase(三)之HBase+Phoenix实现分页
先简单讲讲只用HBase来实现分页的思路: HBase利用scan来扫描表,通过startKey,stopKey来确定扫描范围,在需要进行分页时可以结合HBase提供的PagefFilter过滤扫描的 ...
- 走进C++程序世界------继承和派生
继承和派生 继承是面向对象编程语言的最重要方面之一,正确的使用继承可编写出设计良好,容易于维护和扩展的应用程序.下面是在其他博客中的总结: ****************************** ...
- php常用的操作
一. php配置 1.禁止一些函数disable_functions = eval,assert,popen,passthru,escapeshellarg,escapeshellcmd,passt ...
- nodejs 计算内存使用率
//计算内存使用率 function calcMem(){ let mem_total = os.totalmem(), mem_free = os.freemem(), mem_used = mem ...
- <httpRuntime>
1.在webconfig中httpconfig属性只能出现一次 配置httpRunTime也可以让FileUpload上传更大的文件,不过设置太大了会因用户将大量文件传递到该服务器而导致的拒绝服务攻击 ...
- Java的动态代理机制详解(转)
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- auto 和 decltype (C++11 新增)
红色字体为个人推断,可信度自辨. 蓝色字体为重点. auto类型说明符:使用auto时,编译器会分析表达式,并自动推算出变量所属类型.*auto变量必须有初值 原理:编译器通过 初值 来判断auto变 ...