POJ_1679_The Unique MST(次小生成树)
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
first line contains a single integer t (1 <= t <= 20), the number
of test cases. Each case represents a graph. It begins with a line
containing two integers n and m (1 <= n <= 100), the number of
nodes and edges. Each of the following m lines contains a triple (xi,
yi, wi), indicating that xi and yi are connected by an edge with weight =
wi. For any two nodes, there is at most one edge connecting them.
Output
Sample Input
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 Output
3
Not Unique!
题意:问最小生成树是否唯一。
分析:求次小生成树,推断次小生成树和最小生成树是否相等。
求次小生成树的步骤:
(1)先用Prime求出最小生成树MST,在Prime的同一时候用一个矩阵mmax[ ][ ]记录在MST中连接随意两点u,v的唯一路径中权
值最大的那条边的权值。做法:Prime是每次添加一个节点t。用该点新加入MST的边与它前一个加入MST的点的mmax的值做比较。
(2)枚举最小生成树以外的边,并删除该边所在环上权值最大的边。
(3)取得的全部生成树中权值最小的一棵即为所求。
算法的时间复杂度为O(n^2)。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define maxn 111
#define inf 0x3f3f3f3f int map[maxn][maxn],mmax[maxn][maxn];//map邻接矩阵存图,mmax示最小生成树中i到j的最大边权
bool used[maxn][maxn];//判断该边是否加入最小生成树
int pre[maxn],dis[maxn];//pre用于mmax的构建,装前一个放入MST的结点,dis用于构建MST void init(int n)
{
for (int i=;i<=n;i++)//图初始化
{
for (int j=;j<=n;j++)
{
if (i==j)
{
map[i][j]=;
}
else
{
map[i][j]=inf;
}
}
}
} void read(int m)
{
int u,v,w;
for (int i=;i<m;i++)//读入图
{
scanf("%d%d%d",&u,&v,&w);
map[u][v]=map[v][u]=w;
}
}
int prime(int n)//构建MST
{
int ans=;
bool vis[maxn];
memset(vis,false,sizeof(vis));
memset(used,false,sizeof(used));
memset(mmax,,sizeof(mmax));
for (int i=;i<=n;i++)
{
dis[i]=map[][i];
pre[i]=;//1点为第一个放入MST的点,先设为所有点的前驱结点
}
pre[]=;
dis[]=;
vis[]=true;
for (int i=;i<=n;i++)
{
int min_dis=inf,k;
for (int j=;j<=n;j++)
{
if (vis[j]==&&min_dis>dis[j])
{
min_dis=dis[j];
k=j;
}
}
if (min_dis==inf)//如果不存在最小生成树
{
return -;
}
ans+=min_dis;
vis[k]=true;
used[k][pre[k]]=used[pre[k]][k]=true;//标记为放入MST的点
for (int j=;j<=n;j++)
{
if (vis[j])
{
mmax[j][k]=mmax[k][j]=max(mmax[j][pre[k]],dis[k]);//最小生成树环的最大边
}
if (!vis[j]&&dis[j]>map[k][j])
{
dis[j]=map[k][j];
pre[j]=k;
}
}
}
return ans;//最小生成树的权值之和
}
int smst(int n,int min_ans)//min_ans 是最小生成树的权值和
{
int ans=inf;
for (int i=;i<=n;i++)//枚举最小生成树之外的边
{
for (int j=i+;j<=n;j++)
{
if (map[i][j]!=inf&&!used[i][j])
{
ans=min(ans,min_ans+map[i][j]-mmax[i][j]);//该边次小MST的权值为MST加上该边再减去该边所在环的最大MST边
}
}
}
if (ans==inf)
{
return -;
}
return ans;
}
void solve(int n)
{
int ans=prime(n);
if (ans==-)
{
puts("Not Unique!");
return;
}
if (smst(n,ans)==ans)//次小MST权值等于MST说明MST不唯一
{
printf("Not Unique!\n");
}
else
{
printf("%d\n",ans);
}
}
int main()
{
int t,n,m; scanf("%d",&t);
while (t--)
{
scanf("%d%d",&n,&m);
init(n);
read(m);
solve(n);
} return ;
}
POJ_1679_The Unique MST(次小生成树)的更多相关文章
- POJ_1679_The Unique MST(次小生成树模板)
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 23942 Accepted: 8492 D ...
- POJ1679 The Unique MST[次小生成树]
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 28673 Accepted: 10239 ...
- POJ 1679 The Unique MST (次小生成树 判断最小生成树是否唯一)
题目链接 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. De ...
- 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 Description Given a connected undirec ...
- POJ 1679 The Unique MST (次小生成树)
题目链接:http://poj.org/problem?id=1679 有t组数据,给你n个点,m条边,求是否存在相同权值的最小生成树(次小生成树的权值大小等于最小生成树). 先求出最小生成树的大小, ...
- poj1679The Unique MST(次小生成树模板)
次小生成树模板,别忘了判定不存在最小生成树的情况 #include <iostream> #include <cstdio> #include <cstring> ...
- 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 ...
随机推荐
- Java学习---Java面试基础考核·
Java中sleep和wait的区别 ① 这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类. sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线 ...
- Java遇到的问题、错误——持续更新
内容:dead code.关于eclipse没有js代码提示的解决 持续更新 ######################################################## dead ...
- 页面请求速度慢,TTFB时间长的问题分析
线上环境发现用户请求某个页面时,出现请求速度慢页面卡顿白屏的现象,通过chrome开发工具调试查看Timing,花费在waiting(TTFB)上的时间过长,几秒十几秒不等 TTFB全称Time To ...
- 网络Socket编程(简易qq实现之C/S通信1)
1. 目标:实现两个用户之间的通信,利用的是简单的Socket知识以及简略界面 2. 界面:分为客户端与服务器端(如下图) 3. 基本功能:客户端先向服务器端发送一个消息,这样就可以让客户端与服务器端 ...
- 【[HEOI2016/TJOI2016]字符串】
码农题啊 上来先无脑一个\(SA\)的板子,求出\(SA\)和\(het\)数组 我们只需要从\(sa[i]\in[a,b]\)的所有\(i\)中找到一个\(i\)使得\(sa[i]\)和\(rk[c ...
- C/C++ 格式化读取和读取一行
文件内容 23 21 4 1 1 0 114 1 1 1 8 112 5 0 0 0 114 1 0 0 0 115 52 4 1 0 1 134 4 0 1 12 131 4 1 1 0 133 5 ...
- sprintf格式化字符串安全问题
先看sprintf用法: 定义和用法 sprintf() 函数把格式化的字符串写入变量中. arg1.arg2.++ 参数将被插入到主字符串中的百分号(%)符号处.该函数是逐步执行的.在第一个 % 符 ...
- map详讲<二>
查找元素: Map可以根据健来查找元素,提供方法find(key),如果是这个健对应的元素存在,则返回的是这个健的迭代器iterator,否则返回的是std::end(): 使用find()函数有点笨 ...
- CentOS7图文安装教程
CentOS 7下载: CentOS 7只提供64位版本,虽然有不少国内镜像节点,不过还是觉得通过BT下载是不错的选择.镜像大小6.7G,联通20M光纤下载,不到小时.以下是中国大陆的下载地址列表: ...
- sqoop导数据到hive报错
[root@hadoop1 conf]# sqoop import --connect jdbc:mysql://192.168.122.15:3306/company --username sqoo ...