POJ-1679 The Unique MST(次小生成树、判断最小生成树是否唯一)
http://poj.org/problem?id=1679
Description
Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V', E'), with the following properties:
1. V' = V.
2. T is connected and acyclic.
Definition 2 (Minimum Spanning Tree): Consider an edge-weighted, connected, undirected graph G = (V, E). The minimum spanning tree T = (V, E') of G is the spanning tree that has the smallest total cost. The total cost of T means the sum of the weights on all the edges in E'.
Input
Output
Sample Input
Sample Output
Not Unique!
题意:
给n点m边无重边,求最小生成树是否唯一,如果这棵最小生成树是唯一的那么就输出最小生成树上权的和,不是唯一的就输出Not Unique!
思路:
求次小生成树,如果和最小生成树结果一样则不唯一。
次小生成树:
次小生成树由最小生成树变化而来,通过最小生成树概念可以知道“次小”只需要通过变化最小生成树上的一条边实现,并且要使得这种变化是最小。
给出一篇写的挺好的博客:https://blog.csdn.net/qq_27437781/article/details/70821413
from:https://blog.csdn.net/u011721440/article/details/38735547
判断最小生成树是否唯一:
1、对图中每条边,扫描其它边,如果存在相同权值的边,则标记该边。
2、用kruskal或prim求出MST。
3、如果MST中无标记的边,则MST唯一;否则,在MST中依次去掉标记的边,再求MST,若求得MST权值和原来的MST权值相同,则MST不唯一。
from:https://blog.csdn.net/blue_skyrim/article/details/51338375
次小生成树的求法是枚举最小生成树的每条边,把其中一条边去掉,找到这两点上其他的边,剩下的边形成最小生成树
kuangbin大佬的博客:https://www.cnblogs.com/kuangbin/p/3147329.html
思路:
求最小生成树时,用数组maxval[i][j]来表示MST中i到j最大边权,求完后,直接枚举所有不在MST中的边,替换掉最大边权的边,更新答案
,注意点的编号从0开始
原理:
最小生成树上的不相邻的两点相连必定成成为一个环,所以我们可以尝试枚举这些不相邻的点使他们相连,再删除环中属于最小生成树的最大边(令当前被确定的点为u,已经被确定的点为v,则u--v路径中最大的边要么来自v--pre[u]路径中的最大,要么就是当前被确定的边lowval[u],dp的思想),这样既保证树的结构又能使树的变化最小。这些枚举中最小的结果即为次小生成树。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+;
//const double PI=acos(-1);
#define Bug cout<<"---------------------"<<endl
const int maxn=;
using namespace std; int G[maxn][maxn];//邻接矩阵
int vis[maxn];//判断点有没在最小生成树中
int pre[maxn];//每个点的双亲
int lowval[maxn];//辅助数组
int maxval[maxn][maxn];//maxval[i][j]表示在最小生成树中从i到j的路径中的最大边权
int used[maxn][maxn];//判断这条边是否在最小生成树中使用过
int MST;//最小生成树权值和 int Prim(int n,int st)//n为顶点的个数,st为最小生成树的开始顶点
{
fill(lowval,lowval+n,INF);
memset(maxval,,sizeof(maxval));
memset(pre,-,sizeof(pre));
memset(used,,sizeof(used));
memset(vis,,sizeof(vis));
int ans=;
lowval[st]=;
vis[st]=;
for(int i=;i<n;i++)
{
if(i!=st&&G[st][i]!=INF)
{
lowval[i]=min(lowval[i],G[st][i]);
pre[i]=st;
}
}
for(int k=;k<n-;k++)
{
int MIN=INF;
int t=-;
for(int i=;i<n;i++)
{
if(vis[i]==&&lowval[i]<MIN)
{
MIN=lowval[i];
t=i;
}
}
// if(MIN==INF) return -1;
ans+=MIN;
vis[t]=;
used[t][pre[t]]=used[pre[t]][t]=;//标记这条边在最小生成树中
for(int i=;i<n;i++)
{
if(vis[i])
maxval[t][i]=maxval[i][t]=max(maxval[i][pre[t]],lowval[t]);
if(i!=t&&!vis[i]&&G[t][i]<lowval[i])
{
pre[i]=t;
lowval[i]=G[t][i];
}
}
}
return ans;
} int Judge(int n)
{
int MIN=INF;
for(int i=;i<n;i++)
{
for(int j=i+;j<n;j++)
{
if(G[i][j]!=INF && !used[i][j])//边不在最小生成树中
MIN=min(MIN,MST-maxval[i][j]+G[i][j]);
}
}
return MIN;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d %d",&n,&m);
memset(G,INF,sizeof(G));
for(int i=;i<m;i++)
{
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
u--;v--;//使标号从0开始
G[u][v]=w;
G[v][u]=w;
}
MST=Prim(n,);
if(MST==Judge(n))//最小生成树和次小生成树总权值相等
printf("Not Unique!\n");
else
printf("%d\n",MST);
}
return ;
}
POJ-1679 The Unique MST(次小生成树、判断最小生成树是否唯一)的更多相关文章
- 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 (次小生成树)
题目链接:http://poj.org/problem?id=1679 有t组数据,给你n个点,m条边,求是否存在相同权值的最小生成树(次小生成树的权值大小等于最小生成树). 先求出最小生成树的大小, ...
- 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 ...
- poj 1679 The Unique MST 【次小生成树】【模板】
题目:poj 1679 The Unique MST 题意:给你一颗树,让你求最小生成树和次小生成树值是否相等. 分析:这个题目关键在于求解次小生成树. 方法是,依次枚举不在最小生成树上的边,然后加入 ...
- POJ 1679 The Unique MST 【最小生成树/次小生成树模板】
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 22668 Accepted: 8038 D ...
- POJ 1679 The Unique MST(判断最小生成树是否唯一)
题目链接: http://poj.org/problem?id=1679 Description Given a connected undirected graph, tell if its min ...
- 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 Total Submissions: 23942 Accepted: 8492 D ...
- poj 1679 The Unique MST
题目连接 http://poj.org/problem?id=1679 The Unique MST Description Given a connected undirected graph, t ...
随机推荐
- 使用GDI+显示OpenCV中的图像IplImage
OpenCV虽然自带了轻量级的界面库HighGUI,但是支持的图像化元素实在是太少了,一般只在前期算法测试时使用.实际产品还是使用MFC库.因此本文记录了如何在GDI+中显示OpenCV中的IplIm ...
- BGP的地址聚合
aggregate-address ip make——多用于地址聚合命令. 但,因此很容易产生路由环路. 所以多加一个参数. as-set as-set,可以是BGP聚合路不丢失原来的AS-Path属 ...
- UE手游如何应对CPU帧率瓶颈和卡顿?
如何高效准确详细的对性能进行剖析?腾讯游戏学院专家Leonn将归纳总结在UE下对每一性能指标的剖析方法,本文重点讲解如何应对CPU帧率瓶颈和卡顿? CPU上帧率低和卡顿是性能优化中最易出现的一部分,尤 ...
- awk 总结
说明:本文源于“朱双印博客”,原文地址:http://www.zsythink.net/archives/tag/awk awk 命令: 综合: awk功能是对“文本”进行格式化输出,形成报表:awk ...
- SQL inner join, join, left join, right join, full outer join
基本信息 创建两个表a1, a2. 两个表的重要差别是:a1 中有5,'wu',a2中没有. a2中有 4,'li',而a1中没有. 创建表和插入数据的代码如下: -- 创建a1表 create ta ...
- 2020/2/5 php编程学习
一事无成的上午..就安了框架解决了一些报错信息 下面简单了解一下 安装一下框架: 什么是路由: 系统从URI(唯一资源定位器)参数中分析出当前请求的分组(平台),控制器和操作方法的过程就是路由. UR ...
- Codeforces 1299B/1300D - Aerodynamic
题目大意: 给定一个图形S,让这个图形任意平移,但是要保证原点(0,0)一直在它的内部或者边上 最后把它能移动到的所有位置进行拼合可以得到一个图形T 问图形S与图形T是否相似 点会按照逆时针顺序给出 ...
- 新iPhone上市会让富士康迎来新一轮的“用工荒”吗?
新iPhone上市,在接下来的几个月内,中国制造会迎来一段非常忙碌或者说忙乱的日子,之所以说忙碌,是在于苹果的订单量常常大得吓人,而之所以说忙乱,则在于连同富士康.和硕.绿点科技等制造业巨头都可能遭遇 ...
- StarUML类图相关——关联、聚合、组合、泛化、依赖、实现
在阅读设计模式相关的书籍,或者其他一些项目.相关博客等等,经常会遇到类图,它对于一个类的信息,如变量.方法及其可见性,类与类(接口)之间的继承关系.依赖关系.聚合关系.组合关系等,都可以比较形象得当地 ...
- 牛客小白月赛18——Forsaken的三维数点
这个是一个简单题,不过因为想到比标程时间复杂度更低的方法就尝试了一下. 思路:虽然加点是三维数点,但是我们要求的是半径的大小,这样的话,就可以转变为一维的问题. 标程的解法是,用树状数组维护,然后二分 ...