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 ...
随机推荐
- 沉淀再出发:spring boot的理解
沉淀再出发:spring boot的理解 一.前言 关于spring boot,我们肯定听过了很多遍了,其实最本质的东西就是COC(convention over configuration),将各种 ...
- August 14th 2017 Week 33rd Monday
Life is like a watch, you can return to the starting point, they are not yesterday! 人生就像钟表,可以回到起点,却已 ...
- Python 处理脚本的命令行参数(三):使用argparse
# coding:utf-8 # 测试argparse模块的基本用法 import argparse # 创建参数解析对象,并添加脚本用法帮助 parser = argparse.ArgumentPa ...
- jq实现鼠标经过出现上拉菜单
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- Dockerfile.md
Docker 使用 前提条件 Docker目前只能在64位CPU架构的计算机上运行(目前只能是x86_64 .amd64). Linux 3.8 或 更高版本的内核.3.8之前的版本也能运行,但效果不 ...
- C++中在子类实现父类的方法调用
- 【[TJOI2017]异或和】
这道题挺神仙的,毕竟这个异或是需要进位的 看到区间和我们很自然的就想到了前缀和 于是处理一下前缀和答案就变成了这个样子 \[⊕\sum_{i=1}^n\sum_{j=1}^{i}pre_i-pre_{ ...
- P1346 电车
题目描述 在一个神奇的小镇上有着一个特别的电车网络,它由一些路口和轨道组成,每个路口都连接着若干个轨道,每个轨道都通向一个路口(不排除有的观光轨道转一圈后返回路口的可能).在每个路口,都有一个开关决定 ...
- Web项目打成war包部署到tomcat时报MySQL Access denied for user 'root'@'localhost' (using password: YES)错误解决方案
Web项目使用使用root账号root密码进行部署,通过Eclipse加载到Tomcat服务器可以发布成功,打成war包放到tomcat的webapps目录无法发布成功,报错: jdbc.proper ...
- Python--BeautifulSoup库安装
1.BeautifulSoup简介 BeautifulSoup库通过解析文档可以获取网页文档中所需的数据,方便用户从HTML或XHTML文档中提取数据,作为python的一个辅助工作,也是爬虫实践中的 ...