POJ1679 The Unique MST(次小生成树)
可以依次枚举MST上的各条边并删去再求最小生成树,如果结果和第一次求的一样,那就是最小生成树不唯一。
用prim算法,时间复杂度O(n^3)。
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 111
#define INF (1<<30)
struct Edge{
int u,v;
}edge[MAXN];
int NE; int n,G[MAXN][MAXN];
int lowcost[MAXN],nearvex[MAXN];
int prim(bool statue){
for(int i=;i<=n;++i) lowcost[i]=INF;
lowcost[]=;
int res=;
for(int i=; i<n; ++i){
int u=-,min=INF;
for(int v=; v<=n; ++v){
if(lowcost[v]!=- && lowcost[v]<min){
min=lowcost[v];
u=v;
}
}
if(u==-) return -;
if(statue && u!=){
edge[NE].u=nearvex[u]; edge[NE].v=u;
++NE;
}
lowcost[u]=-;
res+=min;
for(int v=; v<=n; ++v){
if(lowcost[v]!=- && lowcost[v]>G[u][v]){
lowcost[v]=G[u][v];
nearvex[v]=u;
}
}
}
return res;
} bool isUnique(int res){
for(int i=; i<NE; ++i){
int tmp=G[edge[i].u][edge[i].v];
G[edge[i].u][edge[i].v]=G[edge[i].v][edge[i].u]=INF;
if(prim()==res) return ;
G[edge[i].u][edge[i].v]=G[edge[i].v][edge[i].u]=tmp;
}
return ;
} int main(){
int t,m,a,b,c;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=; i<=n; ++i){
for(int j=; j<=n; ++j) G[i][j]=INF;
}
for(int i=; i<m; ++i){
scanf("%d%d%d",&a,&b,&c);
G[a][b]=G[b][a]=c;
}
NE=;
int res=prim();
if(isUnique(res)) printf("%d\n",res);
else puts("Not Unique!");
}
return ;
}
有O(n^2)的算法,详见http://www.cnblogs.com/hxsyl/p/3290832.html。
算法,需要求出MST上任意两点路径上的最长边,删除这条边会形成两个连通分支而那两点就分别在这两个连通分支里;
然后依次枚举所有不在MST上的边,删除边上两点路径上的最长边并加入MST,这样就构成另外一颗生成树了,并且是存在该边的前提下的最小生成树。
计算MST任意两点路径上的最长边,可以在prim算法的过程中求出:每当一个点加入T集合前,计算出所有T集合的点到该点的最长边。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 111
#define INF (1<<30) int n,G[MAXN][MAXN];
bool vis[MAXN][MAXN];
int lowcost[MAXN],nearvex[MAXN],maxedge[MAXN][MAXN];
int T[MAXN],NT;
int prim(){
memset(vis,,sizeof(vis));
memset(maxedge,,sizeof(maxedge));
NT=;
nearvex[]=;
for(int i=; i<=n; ++i) lowcost[i]=INF;
lowcost[]=; int res=;
for(int i=; i<n; ++i){
int u=-,mincost=INF;
for(int v=; v<=n; ++v){
if(lowcost[v]!=- && lowcost[v]<mincost){
mincost=lowcost[v];
u=v;
}
} vis[nearvex[u]][u]=vis[u][nearvex[u]]=;
for(int i=; i<NT; ++i) maxedge[T[i]][u]=maxedge[u][T[i]]=max(maxedge[T[i]][nearvex[u]],mincost);
T[NT++]=u; res+=mincost;
lowcost[u]=-;
for(int v=; v<=n; ++v){
if(lowcost[v]!=- && lowcost[v]>G[u][v]){
lowcost[v]=G[u][v];
nearvex[v]=u;
}
}
}
return res;
} int SMST(){
int res=INF;
for(int i=; i<=n; ++i){
for(int j=i+; j<=n; ++j){
if(vis[i][j] || G[i][j]==INF) continue;
res=min(res,G[i][j]-maxedge[i][j]);
}
}
return res;
} int main(){
int t,m,a,b,c;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=; i<=n; ++i){
for(int j=; j<=n; ++j) G[i][j]=INF;
}
while(m--){
scanf("%d%d%d",&a,&b,&c);
G[a][b]=G[b][a]=c;
}
int res=prim();
if(SMST()==) puts("Not Unique!");
else printf("%d\n",res);
}
return ;
}
POJ1679 The Unique MST(次小生成树)的更多相关文章
- POJ1679 The Unique MST[次小生成树]
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 28673 Accepted: 10239 ...
- POJ1679 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,次小生成树模板题
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Description Given a connected undirec ...
- POJ 1679 The Unique MST (次小生成树 判断最小生成树是否唯一)
题目链接 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. De ...
- POJ_1679_The Unique MST(次小生成树)
Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definit ...
- POJ_1679_The Unique MST(次小生成树模板)
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 23942 Accepted: 8492 D ...
- POJ 1679 The Unique MST (次小生成树)
题目链接:http://poj.org/problem?id=1679 有t组数据,给你n个点,m条边,求是否存在相同权值的最小生成树(次小生成树的权值大小等于最小生成树). 先求出最小生成树的大小, ...
- poj1679The Unique MST(次小生成树模板)
次小生成树模板,别忘了判定不存在最小生成树的情况 #include <iostream> #include <cstdio> #include <cstring> ...
- POJ 1679 The Unique MST (次小生成树kruskal算法)
The Unique MST 时间限制: 10 Sec 内存限制: 128 MB提交: 25 解决: 10[提交][状态][讨论版] 题目描述 Given a connected undirect ...
- poj 1679 The Unique MST (次小生成树(sec_mst)【kruskal】)
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 35999 Accepted: 13145 ...
随机推荐
- 通过rails console执行sql语句
$ RAILS_ENV=production bundle exec rails c irb(main):008:0> r = ActiveRecord::Base.connection.exe ...
- nyoj 8
http://acm.nyist.net/JudgeOnline/problem.php?pid=8 #include<stdio.h> #include<iostream> ...
- [转]Ubuntu 系统 Update-rc.d 命令
本文转自:http://wangyan.org/blog/ubuntu-update-rc-d.html 以防止原博客挂掉,特此做了备份. Ubuntu或者Debian系统中update-rc.d命令 ...
- 代码风格与树形DP
Streaming很惨,不过因为比赛之间没有提交过就没掉(或掉了)rating.第二题是一个树形DP,但是我都在想第一题了,简直作死. 看着神犇的代码我也是醉了...各种宏,真是好好写会死系列. 看到 ...
- easyui-datagrid 两次请求
原因分析及解决方案 html代码中利用class声明了datagrid,导致easyUI解析class代码的时候先解析class声明中的datagrid,这样组件就请求了一次url:然后又调用js初始 ...
- spring3.0+Atomikos 构建jta的分布式事务 -- NO
摘自: http://gongjiayun.iteye.com/blog/1570111 spring3.0+Atomikos 构建jta的分布式事务 spring3.0已经不再支持jtom了,不过我 ...
- DropDownList1
循环绑定数据到DropDownList1 foreach (SPList ls in web.Lists) { LIColl.Add(ls.Title);//将数据保存list中 } dwlist.D ...
- poj 2709
http://poj.org/problem?id=2709 题意:就是那个老师需要n瓶颜色的墨水,和1瓶颜色的灰色的墨水,但是灰色的墨水没得卖,只能由三种颜色相同的墨水混合而成,但是3瓶50ML的墨 ...
- 设置windows网络连接别名和linux网络连接别名
windows网络连接别名 C:\Windows\System32\drivers\etc目录下的hosts文件中添加 127.0.0.1 localhost 192.168.1.100 proxy. ...
- VMware安装64位操作系统提示Intel VT-x处于禁用状态的解决办法
用VMware安装64位操作系统时,如果目前本地的操作系统是64位的,那么可以说明CPU是肯定支持64位的,这时候如果提示此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态.这个 ...