次小生成树学习+例题 poj 1679 The Unique MST
次小生成树学习:
顾名思义,次小生成树,就是将图的所有生成树排序后,权值第二小的生成树。
次小生成树的朴素求法是很好想的,即首先求出最小生成树,之后枚举最小生成树中的所有边,将当前枚举的边“禁止使用”,在这基础之上再求最小生成树,将所有边枚举之后的结果取最小值,那就是次小生成树。这个算法简单暴力,但是可想而知的复杂度是比较大的,在图是稠密图的时候,复杂度接近O(n^3)。在规模较大的时候不建议使用。
另一个推荐的求法:在添加最小生成树的边之外的边时,会形成环,这个时候,把在这个环中,且在最小生成树中的边给去掉,这时候就形成了另一个生成树。如何实现这个算法的呢?实际上,对于两个点u,v,我们遍历最小生成树,找出u到v的边中的最大权值的边,用一个数组maxn[u][v]保存起来。当我们往最小生成树中加边时,就直接用w - max[u][v] + 当前添加边的权值,这个式子计算出此时生成树的权值之和。那么maxn[u][v]这个数组是如何求得呢?嗯,bfs,即广度优先搜索,对每一个点都遍历一次生成树,每次更新的值都是当前点到其他点的权值。之后就枚举不在生成树的边进行计算,把每次的结果都保存下来,取最小的,就是次小生成树啦。(或许第k小生成树可以这么求?)这个算法的复杂度为O(n^2)。
例题:
https://vjudge.net/problem/POJ-1679
题意:
这题问的是最小生成树是否唯一。
思路:
那么很显然的,如果说最小生成树不唯一的话,那么最小生成树与次小生成树的权值肯定相等,因为对于在最小生成树中的边来说,至少存在一条不在其中的边,与在其中的边的权值相等,这样才满足不唯一,所以只需要求出次小生成树,判断其与最小生成树是否相等就可以了。
PS:通过这题还学会了用邻接链表表示图,用vector很方便的,就是把以每个点为起点的边搞到一起就ok。
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std; struct node
{
int x,y,w;
} e[]; struct ord
{
int p,dis;
}; vector<node> v[]; int par[];
int maxn[][]; bool used[],vis[]; void init(int n)
{
for (int i = ;i <= n;i++)
par[i] = i;
} int fin(int x)
{
if (x == par[x]) return x;
else return par[x] = fin(par[x]);
} void unit(int x,int y)
{
x = fin(x);
y = fin(y); if (x != y) par[x] = y;
} bool cmp(node aa,node bb)
{
return aa.w < bb.w;
} void adde(int x,int y,int dis)
{
node t;
t.x = x;
t.y = y;
t.w = dis;
v[x].push_back(t);
} void bfs(int k)
{
memset(used,,sizeof(used)); ord now,nex; now.p = k;now.dis = ;
used[k] = true; queue<ord> qq; while (!qq.empty()) qq.pop(); qq.push(now); while (!qq.empty())
{
//printf("dsfsd\n");
ord t = qq.front();qq.pop(); int x = t.p,tmaxn = t.dis; for (int i = ;i < v[x].size();i++)
{
node tt = v[x][i]; nex.dis = tt.w;nex.p = tt.y; if (!used[nex.p])
{
if (tmaxn > nex.dis) nex.dis = tmaxn;
used[nex.p] = true;
maxn[k][nex.p] = nex.dis;
qq.push(nex);
}
}
}
} int main()
{
int t; scanf("%d",&t); while (t--)
{
int n,m; scanf("%d%d",&n,&m); init(n); memset(v,,sizeof(v));
memset(vis,,sizeof(vis));
memset(used,,sizeof(used)); for (int i = ;i < m;i++)
{
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
} sort(e,e+m,cmp); int ans = ; for (int i = ;i < m;i++)
{
int x = e[i].x,y = e[i].y; if (fin(x) == fin(y)) continue; unit(x,y); vis[i] = true; ans += e[i].w; adde(x,y,e[i].w);
adde(y,x,e[i].w);
} for (int i = ;i <= n;i++)
{
bfs(i);
} int minn = ; for (int i = ;i < m;i++)
{
if (!vis[i])
{
int tans = ans;
int x = e[i].x,y = e[i].y; tans -= maxn[x][y]; tans += e[i].w; if (tans < minn) minn = tans;
} } if (minn == ans) printf("Not Unique!\n");
else printf("%d\n",ans);
} return ;
}
次小生成树学习+例题 poj 1679 The Unique MST的更多相关文章
- 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 The Unique MST Description Given a connected undirected graph, t ...
- 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 有t组数据,给你n个点,m条边,求是否存在相同权值的最小生成树(次小生成树的权值大小等于最小生成树). 先求出最小生成树的大小, ...
- POJ 1679 The Unique MST:次小生成树【倍增】
题目链接:http://poj.org/problem?id=1679 题意: 给你一个图,问你这个图的最小生成树是否唯一. 题解: 求这个图的最小生成树和次小生成树.如果相等,则说明不唯一. 次小生 ...
- POJ 1679 The Unique MST(次小生成树)
题意:求解最小生成树的权值是否唯一,即要我们求次小生成树的权值两种方法求最小生成树,一种用prim算法, 一种用kruskal算法 一:用prim算法 对于给定的图,我们可以证明,次小生成树可以由最小 ...
- poj 1679 The Unique MST【次小生成树】
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 24034 Accepted: 8535 D ...
随机推荐
- 第一天上午——HTML网页基础知识以及相关内容
今天上午学习了HTML基础知识以及相关内容,还有DW的基本使用方法. HTML(HyperText Markup Language):超文本标记语言,超文本:网页中除了包含文本文字之外,还包含了图片, ...
- IIC协议学习笔记
"移植"的重要性:并非所有的电路都得自己设计,到了一定阶段,"移植"也是一种学习能力.--CrazyBingo 转眼间期末又到了,最近开始了所谓的期末总预习,比 ...
- .Net开发的两个小技巧
一.@符号的妙用 1.可以作为保留关键字的标识符 C#规范当中,不允许使用保留关键字(class.bool等)当作普通的标识符来命名,这时候@符号作用就体现 出来了,可以通过@符号前缀把这些保留关键字 ...
- 关于sqlmap的一些命令
Options(选项):--version 显示程序的版本号并退出-h, --help 显示此帮助消息并退出-v VERBOSE 详细级别:0-6(默认为1)Target(目标):以下至少需要设置其中 ...
- String 类问题发现与解决
1.在代码中出现:String t = null; t.length(); 执行后:控制台报:java.lang.NullPointerException 原因:Java中,null是一个关键字,用来 ...
- Elasticsearch重要配置
虽然Elasticsearch需要很少的配置,但是有一些设置需要手动配置,并且必须在进入生产之前进行配置. path.data and path.logs cluster.name node.nam ...
- LoadRunner11_录制Oracle数据库脚本
[oracle环境] ①oracle:无需在本地安装oracle,但是oracle的odbc驱动一定要装:(我的安装路径为 D:\oracle ).安装好后在环境变量 " Path &quo ...
- PHPCMS V9 为今天或几天前文章加new
今天内发布: {pc:content action="lists" catid="13" order="listorder DESC" nu ...
- js传宗接代---继承
前几天重温了一下js的继承,今天分享给大家: 一,类式继承. 所谓的类式继承就是:第二个类的原型prototype被赋予了第一个类的实例,如subcals.prototype=new supercls ...
- java编码详解
举个例子 我们在开发过程中,特别是多种编码格式并存的情况下,很容易遇到乱码问题. 假如有一个GBK编码java文件,然后再使用-Dfile.encoding=GBK参数,写入的文件中哪些是乱码呢.那如 ...