次小生成树的求法:

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 次小生成树的更多相关文章

  1. The Unique MST POJ - 1679 次小生成树prim

    求次小生成树思路: 先把最小生成树求出来  用一个Max[i][j] 数组把  i点到j 点的道路中 权值最大的那个记录下来 used数组记录该条边有没有被最小生成树使用过   把没有使用过的一条边加 ...

  2. The Unique MST POJ - 1679 (次小生成树)

    Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spann ...

  3. poj 2831 次小生成树模板

    /*次小生成树 题意:给你一些路径,现在将一部分路径权值减少后问是否可以替代最小生成树里面的边. 解:次小生成树,即将这条边连上,构成一个环 求出任意两点路径之间的除了这条边的最大值,比较这个最大值& ...

  4. The Unique MST-POJ1679(次小生成树)

    http://poj.org/problem?id=1679 次小生成树 #include<stdio.h> #include<string.h> #include<st ...

  5. POJ1679 The Unique MST[次小生成树]

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28673   Accepted: 10239 ...

  6. POJ 1679 The Unique MST (次小生成树)

    题目链接:http://poj.org/problem?id=1679 有t组数据,给你n个点,m条边,求是否存在相同权值的最小生成树(次小生成树的权值大小等于最小生成树). 先求出最小生成树的大小, ...

  7. poj 1679 The Unique MST 【次小生成树】【模板】

    题目:poj 1679 The Unique MST 题意:给你一颗树,让你求最小生成树和次小生成树值是否相等. 分析:这个题目关键在于求解次小生成树. 方法是,依次枚举不在最小生成树上的边,然后加入 ...

  8. 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 ...

  9. POJ 1679 The Unique MST:次小生成树【倍增】

    题目链接:http://poj.org/problem?id=1679 题意: 给你一个图,问你这个图的最小生成树是否唯一. 题解: 求这个图的最小生成树和次小生成树.如果相等,则说明不唯一. 次小生 ...

随机推荐

  1. BAT-使用BAT方法结束进程(删除进程)

    @echo off taskkill /f /im GAM.exe taskkill /f /im GCL10.exe

  2. Mac下的截屏功能

    全屏截图 对全屏的截图我们可以通过按 苹果键(花键)+Shift键+3来执行,之后伴随着清脆的一声提示音后,在桌面上就会生成一个图片文件,这就是刚刚截屏的图片了,默认文件类型是PNG的. 自定义截图 ...

  3. linux系统日常管理

    笔者在前面介绍的内容都为linux系统基础类的,如果你现在把前面的内容全部很好的掌握了,那最好了.不过笔者要说的是,即使你完全掌握了,你现在还是不能作为一名合格的linux系统管理员的,毕竟系统管理员 ...

  4. 关于mysql_fetch_****

    今天调试如下代码: mysql_select_db('content',$link);//选择数据库 mysql_query("set names utf8");//设置编码格式 ...

  5. SQl函数的写法

    USE [ChangHong_612]GO/****** Object: UserDefinedFunction [dbo].[FN_GetProdQty] Script Date: 10/08/20 ...

  6. IOS学习网址

    iOS定位和位置信息获取 http://www.cnblogs.com/496668219long/p/4471757.html iOS开发系列--并行开发其实很容易 http://www.cnblo ...

  7. update多表更新的2种方式

    update t1 set TermBeginQty =isnull((select top 1 JiaoPlusQty from WMS_RptMaterialPutDaily r where t1 ...

  8. 配置 Spring 的声明式事务

    <!-- 1. 配置事务管理器 --> <bean id="transactionManager" class="org.springframework ...

  9. Unity3D-Baked Lightmapping 示例学习

    首先,看一下摄像机的Rendering Paths http://game.ceeger.com/Manual/RenderingPaths.html 可以看出,对于灯光的渲染质量 Deferred ...

  10. 【转】C++笔试题汇总

    原文:http://www.cnblogs.com/ifaithu/articles/2657663.html C#C++C多线程面试1.static有什么用途?(请至少说明两种)1)在函数体,一个被 ...