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 ...
随机推荐
- 搭建openfire Android 客户端学习和开发【二】spark源码导入eclipse
首先声明下 这是我在eoe上转载的 写的很好就摘抄了... 第一步 下载源码 svn下载,下载地址:spark:http://svn.igniterealtime.org/svn/repos/spar ...
- [Effective JavaScript 笔记]第55条:接收关键字参数的选项对象
53节建议保持参数顺序的一致约定对于帮助程序员记住每个参数在函数调用中的意义很重要.参数较少这个主意不错,但如果参数过多后,就出现麻烦了,记忆和理解起来都不太容易. 参数蔓延 如下面这些代码: var ...
- Apache VirtualHost配置
转载:http://www.cnblogs.com/wpjsolo/archive/2012/01/19/2327457.html 以lampp环境为例子,其他环境只是配置文件的路径不同. 先要在 ...
- zb的生日
http://acm.nyist.net/JudgeOnline/problem.php?pid=325 zb的生日 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 ...
- 记录:js删除数组中某一项或几项的几种方法
1:js中的splice方法 splice(index,len,[item]) 注释:该方法会改变原始数组. splice有3个参数,它也可以用来替换/删除/添加数组内某一个或者几个值 inde ...
- 【OpenStack】OpenStack系列1之Python虚拟环境搭建
安装virtualenv相关软件包 安装:yum install python-virtualenv* -y 简介,安装包主要包括, python-virtualenv:virtualenv用于创建独 ...
- 烦烦烦SharePoint2013 以其他用户登录和修改AD域用户密码
sharepoint默认是没有修改AD密码 和切换 用户的功能,这里我用future的方式来实现. 部署wsp前: 部署后 点击以其他用户身份登录 点击修改用户密码: 这里的扩展才菜单我们用Custo ...
- Linux下提取IP至文件
ifconfig | grep 'inet[^6]' | sed 's/^\s*//g' | cut -d ' ' -f2 > ips.txt 排除127开头的IP: ifconfig | gr ...
- (转)使用SQLCMD在SQLServer执行多个脚本
概述: 作为DBA,经常要用开发人员提供的SQL脚本来更新正式数据库,但是一个比较合理的开发流程,当提交脚本给DBA执行的时候,可能已经有几百个sql文件,并且有执行顺序,如我现在工作的公司,十几个客 ...
- eclipse字体的设置
eclipse的默认字体太小,所以设置的大一些比较清楚,方法很简单,单击菜单栏的"Window"选择"Preferences",如下图: 然后左侧依次选择Gen ...