【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 ...
随机推荐
- C# 操作IE浏览器
最近的一个B/S系统中,用到了指模录入,当用户按了手指摸之后,要在IE浏览器的一个文本框上显示用户的姓名.由于要监控指模机的输入,因此客户端需要装一个.net控制台程序,通过此控制台程序监控指模机.这 ...
- 【Xamarin挖墙脚系列:Xamarin.IOS的多个Storybord分隔视图的导航】
在实际开发中,我是推荐使用画板Storybord的.也可以适当的添加xib进行界面的绘制.尽量不要用或者少用代码绘制视图.(少一些装B分子,可以极大的缩短项目的周期). 不要讲性能,不是不讲性能,ap ...
- ARM架构和X86架构对比
转载地址 我们就ARM架构的系统与X86架构系统的特性进行一个系统分析,方便用户在选择系统时进行理性.合理的比价分析. 一.性能: X86结构的电脑无论如何都比ARM结构的系统在性能方面要快得多.强得 ...
- UVA_Digit Puzzle UVA 12107
If you hide some digits in an integer equation, you create a digit puzzle. The figure below shows tw ...
- html中隐藏域hidden的作用
基本语法: <input type="hidden" name="field_name" value="value"> 作用: ...
- hdu2208之搜索
唉,可爱的小朋友 Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- HDU2037 贪心 动归均可+证明
今年暑假不AC Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...
- linux下ACE使用epoll
select和epoll的比较就不用多说了.ACE在linux下默认使用select来实现Reactor的.如何在linux下让ACE使用epoll. 1.加一个编译宏,告诉ACE不要使用默认的sel ...
- 克隆虚拟机,如何将克隆虚拟的网卡设置为eth0
1.先删掉/etc/udev/rules.d/70-persistent-net.rules文件里的eth0,并要记住eth1的那个网卡的mac地址等下要用.2.把那个eth1修改为eth03.编辑网 ...
- Vlc基础数据结构记录
1. Vlc基础数据结构 hongxianzhao@hotmail.com 1.1 基础数据结构 struct vlc_object_t,相关文件为src\misc\objects.c. 定义为: ...