次小生成树学习+例题 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 ...
随机推荐
- Mac 多个JDK的版本 脚本切换
这里配置jdk7和jdk8版本的切换 1.官网下载jdk7和jdk8 地址:http://www.oracle.com/technetwork/java/javase/downloads 2.安装两个 ...
- Android React Native 开发环境搭建---windows下
环境搭建 环境搭建可以参考RN官网,也可以参考中文版本:http://reactnative.cn/docs/0.45/getting-started.html 如果你希望可以看到原版的安装流程,可以 ...
- python os模块学习
一.os模块概述 Python os模块包含普遍的操作系统功能.如果你希望你的程序能够与平台无关的话,这个模块是尤为重要的. 二.常用方法 1.os.name 输出字符串指示正在使用的平台.如果是wi ...
- MyEclipse解决SVN同步冲突问题conflict in the working copy obstructs the current operation
服务端版本控制软件subversion,客户端是eclipse的插件subclipse.当删除一个东西的时候老是提示错误,说冲突 commit -m "" C:/Users/Adm ...
- Java之戳中痛点 - (7)善用Java整型缓存池
先看一段代码: package com.test; import java.util.Scanner; public class IntegerCache { public static void m ...
- 日常踩坑 searter
目录 es7中的async, await Django生成二维码并转为base64 Django配置404页面 很傻逼的坑 no module named pil 其他 es7中的async, awa ...
- SQL Server2012数据库的备份和还原
一.数据库的备份: 1.选择要备份的数据库“accountInfo”,点击鼠标右键 → 任务 → 备份 2.在打开的“备份数据库 —accountInfo”对话框中,先点击删除,然后点击“添加” 3. ...
- AutoMapper5.0创建对象方法更新
/// <summary> /// 单个对象映射 /// </summary> public static TDestination MapTo<TSource, TDe ...
- phpcmsV9手机站内容页有时内容不显示
phpcmsV9手机站内容页有时内容不显示,修改的办法是: 在文件phpcms\modules\wap\index.php 中 屏蔽第119行,即如下内容 //$content = $contentp ...
- vmware安装FreeBSD8.3全攻略【教程】
原始日期:2013-08-02 23:15 前言:花了两天时间倒腾这个freebsd,安装并不简单,如果单单参照百度上的教程是会遇到各种问题的,所以我打算自己写一篇教程,为了更加直观,部分采用了互联网 ...