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 ...
随机推荐
- LightOJ - 1282 Leading and Trailing (数论)
题意:求nk的前三位和后三位. 分析: 1.后三位快速幂取模,注意不足三位补前导零. 补前导零:假如nk为1234005,快速幂取模后,得到的数是5,因此输出要补前导零. 2.前三位: 令n=10a, ...
- css ~ a标签占满父级元素
width: 100%; height: 100%; display: block;
- PHP常用的数学函数和字符串函数
PHP常用函数总结 数学函数 1.abs(): 求绝对值 $abs = abs(-4.2); //4.2 数字绝对值数字 2.ceil(): 进一法取整 echo ceil(9.999); // 10 ...
- 76.Python中F表达式详解
F表达式是用来优化ORM操作数据库的. 举个例子:我们做口罩的公司要将所有员工的薪水增加2000元,如果按照正常的流程,应该是先从数据库中提取所有的员工的工资到Python内存中,然后使用Python ...
- 字符,字符串,int之间互相转换
字符转换成字符串:String str = String.valueOf(ch); 字符转换成int: int a = ch; 字符串转换成字符:char ch = str.charAt(0); 字符 ...
- stm32cube 安装 patch
首先正常安装芯片包,然后在设置里面找到当前包存放的位置,默认是: C:\Users\Administrator\STM32Cube\Repository 然后解压 更新包,把更新包里面的文件覆盖到 C ...
- trove module使用说明
原文来自:https://github.com/openstack/openstack-manuals/blob/master/doc/user-guide/source/database-modul ...
- Python连接Oracle问题
Python连接Oracle问题 1.pip install cx_oracle 2.会出现乱码问题: 方法一:配置环境变量 export NLS_LANG="SIMPLIF ...
- winform屏蔽鼠标右键
/// <summary> /// 屏蔽右键 /// </summary> internal class MenuHandler : IContextMenuHandler { ...
- 深入JVM(一)JVM指令手册
本文按照如下思维导图组织 1. 栈和局部变量操作 1.1 将常量压入栈的指令 aconst_null 将null对象引用压入栈iconst_m1 将int类型常量-1压入栈iconst_0 将int类 ...