poj 1679 次小生成树
次小生成树的求法:
1.Prime法
定义一个二维数组F[i][j]表示点i到点j在最小生成树中的路径上的最大权值。有个知识就是将一条不在最小生成树中的边Edge加入最小生成树时,树中要去掉的边就是Edge连接的两个端点i,j的F[i][j]。这样就能保存找到的生成树时次小生成树。
代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define inf 1<<30
#define Maxn 102
#define Maxm 10010
#define USE 2
#define EXIST 1
#define NOTEXIST 0
using namespace std;
int map[Maxn][Maxn],dist[Maxn],vi[Maxn],f[Maxn][Maxn],use[Maxn][Maxn],pre[Maxn];
int n,m;
int prime(int src)
{
int i,j,Min,index;
int ans=;
memset(vi,,sizeof(vi));
memset(pre,-,sizeof(pre));
for(i=;i<=n;i++)
dist[i]=inf;//一定要初始化为inf,这样以第一个点开始,使与第一个相连的节点的前节点为第一个节点。
dist[]=;//以第一个节点开始
for(i=;i<=n;i++)
{
Min=inf;
for(j=;j<=n;j++)
{
if(!vi[j]&&dist[j]<Min)
{
Min=dist[j];
index=j;
}
}
if(pre[index]!=-)//如果存在前节点
{
use[index][pre[index]]=use[pre[index]][index]=USE;//标记为使用过
for(j=;j<=n;j++)
if(vi[j])//对树种已存在的点进行更新
f[j][index]=max(f[j][pre[index]],map[index][pre[index]]);
}
ans+=Min;
vi[index]=;
//cout<<Min<<"*"<<endl;
for(j=;j<=n;j++)
{
if(!vi[j]&&dist[j]>map[index][j])
{
dist[j]=map[index][j];
pre[j]=index;
}
}
}
//cout<<ans<<"*"<<endl;
return ans;
}
int secondmst(int mst)
{
int i,j,ans;
ans=inf;
for(i=;i<=n;i++)
for(j=;j<=n;j++)
if(use[i][j]==EXIST)
{
if(mst+map[i][j]-f[i][j]<ans)//求次小生成树
ans=mst+map[i][j]-f[i][j];
}
//cout<<ans<<"*"<<endl;
return ans;
}
void init()//初始化
{
int i,j;
memset(f,,sizeof(f));
for(i=;i<=Maxn-;i++)
for(j=;j<=Maxn-;j++)
map[i][j]=map[j][i]=inf;
memset(use,,sizeof(use));
}
int main()
{
int i,j,a,b,c,t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
for(i=;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
map[a][b]=map[b][a]=c;
use[a][b]=use[b][a]=;
}
int ans1=prime();
int ans2=secondmst(ans1);
if(ans1==ans2)
printf("Not Unique!\n");
else
printf("%d\n",ans1);
}
return ;
}
kruskaer的算法就相对简单,就是先求一边最下生成树,将树中的边保存下来。然后每次去掉一个边,重求最小生成树,找出最小的便是次小生成树。
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
struct Edge{
int x,y,c;
int operator <(const Edge &temp) const
{
return c<temp.c;
}
}edge[];
int set[],e,vi[],p[],index;
int find(int x)
{
if(x!=set[x])
set[x]=find(set[x]);
return set[x];
}
void init()
{
e=;
index=;
for(int i=;i<=;i++)
set[i]=i;
memset(vi,,sizeof(vi));
}
int main()
{
int t,n,m,i,j,x,y,c;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d%d",&n,&m);
for(i=;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&c);
edge[i].x=x,edge[i].y=y,edge[i].c=c;
}
sort(edge+,edge+m+);
int num=;
int ans=;
for(i=;i<=m;i++)//先求一边最小生成树
{ //cout<<edge[i].c<<"*"<<endl;
x=find(edge[i].x);
y=find(edge[i].y);
if(x==y)
continue;
p[index++]=i;//将树中的每条边保存起来
set[x]=y;
ans+=edge[i].c;
num++;
if(num==n-)
break;
}
int ans2=,num2=;
int f=;
for(i=;i<index;i++)//在枚举每次删除一条边后,求最小生成树
{
for(j=;j<=;j++)
set[j]=j;
ans2=,num2=;
for(j=;j<=m;j++)
{
if(j==p[i])
continue;
x=find(edge[j].x);
y=find(edge[j].y);
if(x==y)
continue;
set[x]=y;
ans2+=edge[j].c;
num2++;
if(num2==n-)
break;
}
if(num2!=n-)
continue;
if(ans==ans2)//若删除某条边后的最小权值与原来相同,那么最小生成树不唯一
{
f=;
break;
}
}
if(!f)
printf("%d\n",ans);
else
printf("Not Unique!\n");
}
return ;
}
poj 1679 次小生成树的更多相关文章
- The Unique MST POJ - 1679 次小生成树prim
求次小生成树思路: 先把最小生成树求出来 用一个Max[i][j] 数组把 i点到j 点的道路中 权值最大的那个记录下来 used数组记录该条边有没有被最小生成树使用过 把没有使用过的一条边加 ...
- The Unique MST POJ - 1679 (次小生成树)
Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spann ...
- poj 2831 次小生成树模板
/*次小生成树 题意:给你一些路径,现在将一部分路径权值减少后问是否可以替代最小生成树里面的边. 解:次小生成树,即将这条边连上,构成一个环 求出任意两点路径之间的除了这条边的最大值,比较这个最大值& ...
- The Unique MST-POJ1679(次小生成树)
http://poj.org/problem?id=1679 次小生成树 #include<stdio.h> #include<string.h> #include<st ...
- POJ1679 The Unique MST[次小生成树]
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 28673 Accepted: 10239 ...
- POJ 1679 The Unique MST (次小生成树)
题目链接:http://poj.org/problem?id=1679 有t组数据,给你n个点,m条边,求是否存在相同权值的最小生成树(次小生成树的权值大小等于最小生成树). 先求出最小生成树的大小, ...
- poj 1679 The Unique MST 【次小生成树】【模板】
题目:poj 1679 The Unique MST 题意:给你一颗树,让你求最小生成树和次小生成树值是否相等. 分析:这个题目关键在于求解次小生成树. 方法是,依次枚举不在最小生成树上的边,然后加入 ...
- poj 1679 The Unique MST 【次小生成树+100的小数据量】
题目地址:http://poj.org/problem?id=1679 2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2 Sample Outpu ...
- POJ 1679 The Unique MST:次小生成树【倍增】
题目链接:http://poj.org/problem?id=1679 题意: 给你一个图,问你这个图的最小生成树是否唯一. 题解: 求这个图的最小生成树和次小生成树.如果相等,则说明不唯一. 次小生 ...
随机推荐
- CodeForces 455B A Lot of Games (博弈论)
A Lot of Games 题目链接: http://acm.hust.edu.cn/vjudge/contest/121334#problem/J Description Andrew, Fedo ...
- JSF 2 hidden value example
In JSF, you can use the <h:inputHidden /> tag to render a HTML hidden value field. For example ...
- HDU1973 http://acm.hdu.edu.cn/showproblem.php?pid=1973
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<queue> #inc ...
- ID生成器详解
概述 ID 生成器也叫发号器,它的主要目的就是"为一个分布式系统的数据object产生一个唯一的标识",但其实在一个真实的系统里可能也可以承担更多的作用.概括起来主要有以下几点: ...
- Java学习笔记(四):流程控制
if语句 if判断语句比较简单,具体有下面的几种写法: int i = 0; // if 判断 if (i == 0) { // to do something } // if else 判断 if ...
- List、ArrayList、Vector及map、HashTable、HashMap分别的区别
一.List与ArrayList的区别 List->AbstractList->ArrayList (1) List是一个接口,ArrayList是一个实现了List接口 ...
- PHP linux spl_autoload_register区分大小写
一个PHP脚本用到spl_autoload_register,在WINDOWS下运行正常,但在LINUX就include不了,后来发现WINDOWS大小写不敏感,而在LINUX下区分大小写,WINDO ...
- idea 搭建java项目
IntelliJ IDEA 12.0搭建Maven Web SSH2架构项目示例 以IDEA为环境,搭建SSH架构示例程序,用Maven管理依赖.这篇文章是一个示例,你需要首先搭建好M ...
- hdu 5563 Clarke and five-pointed star 水题
Clarke and five-pointed star Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/show ...
- c# 将PPT转换成HTML
这只是一个小程序,就是将ppt转换成html,方法很多,为了以后备用,在此记录一下,也和大家分享 源码如下: using System; using System.Collections.Generi ...