题目链接:

https://vjudge.net/problem/POJ-1679

题目大意:

给定一个无向连通网,判断最小生成树是否唯一。

思路:

(1)对图中的每条边,扫描其他边,如果存在相同权值的边,对该边做标记。

(2)然后用kruskal算法或者prim算法求MST(标记MST中的边)

(3)求得MST后,如果MST中未包含做了标记的边,那么MST唯一。

MST中不包含未标记的边,说明MST中没有那些权值相同的边,用kruskal算法可知,该最小生成树肯定唯一。

(4)如果包含标记的边,依次去掉这些边,再求MST,如果所求的MST权值和之前的MST权值一样说明最小生成树不唯一,反之,则唯一。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + ;
const int INF = << ;
int dir[][] = {,,,,-,,,-};
int T, n, m, x;
bool first;
struct edge
{
int u, v, w;
bool used, equal, del;//used表示是否在MST中,equal表示边是否是相等,del表示求MST中删除的边
bool operator <(const edge& a)const
{
return w < a.w;
}
};
edge a[maxn];
int par[], high[];
//初始化n个元素
void init(int n)
{
for(int i = ; i < n; i++)
{
par[i] = i;
high[i] = ;
}
}
//查询树的根
int Find(int x)
{
return par[x] == x ? x : par[x] = Find(par[x]);//路径压缩
}
void unite(int x, int y)
{
x = Find(x);
y = Find(y);
if(x == y)return;
if(high[x] < high[y])par[x] = y;//y的高度高,将x的父节点设置成y
else
{
par[y] = x;
if(high[x] == high[y])high[x]++;
}
}
int kruskal(int n, int m)//点数n,边数m
{
int sum_mst = ;//mst权值
int num= ;//已经选择的边的边数
sort(a, a + m);//边进行排序
init(n);//初始化并查集
for(int i = ; i < m; i++)
{
int u = a[i].u;
int v = a[i].v;
if(a[i].del)continue;
if(Find(u - ) != Find(v - ))//图最开始的下标是1,并查集是0
{
//printf("%d %d %d\n", u, v, a[i].w);
sum_mst += a[i].w;
num++;
unite(u - , v - );
if(first)a[i].used = ;//标记第一次MST的边
}
if(num >= n - )break;
}
//printf("weight of mst is %d\n", sum_mst);
return sum_mst;
}
int main()
{
cin >> T;
while(T--)
{
cin >> n >> m;
for(int i = ; i < m; i++)
{
cin >> a[i].u >> a[i].v >> a[i].w;
a[i].used = a[i].equal = a[i].del = ;
}
sort(a, a + m);
for(int i = ; i < m; i++)//标记权值相同的边
{
int j = i + ;
for(; j < m; j++)
{
if(a[j].w == a[i].w)a[i].equal = a[j].equal = ;
else break;
}
i = j - ;
}
first = ;
int mst1 = kruskal(n, m);
first = ;
int flag = ;
for(int i = ; i < m; i++)
{
if(a[i].used && a[i].equal)//依次删除第一次MST中相等的边,再次求MST
{
a[i].del = ;
int mst2 = kruskal(n, m);
if(mst1 == mst2)
{
flag = ;
cout<<"Not Unique!"<<endl;
break;
}
a[i].del = ;//删除的标记清除
}
}
if(!flag)cout<<mst1<<endl;
}
return ;
}

POJ-1679 The Unique MST---判断最小生成树是否唯一的更多相关文章

  1. poj 1679 The Unique MST 判断最小生成树是否唯一(图论)

    借用的是Kruskal的并查集,算法中的一点添加和改动. 通过判定其中有多少条可选的边,然后跟最小生成树所需边做比较,可选的边多于所选边,那么肯定方案不唯一. 如果不知道这个最小生成树的算法,还是先去 ...

  2. poj 1679 The Unique MST (判定最小生成树是否唯一)

    题目链接:http://poj.org/problem?id=1679 The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total S ...

  3. POJ 1679 The Unique MST 推断最小生成树是否唯一

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 22715   Accepted: 8055 D ...

  4. 【POJ 1679 The Unique MST】最小生成树

    无向连通图(无重边),判断最小生成树是否唯一,若唯一求边权和. 分析生成树的生成过程,只有一个圈内出现权值相同的边才会出现权值和相等但“异构”的生成树.(并不一定是最小生成树) 分析贪心策略求最小生成 ...

  5. POJ 1679 The Unique MST(最小生成树)

    Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definit ...

  6. POJ 1679 The Unique MST (最小生成树)

    The Unique MST 题目链接: http://acm.hust.edu.cn/vjudge/contest/124434#problem/J Description Given a conn ...

  7. POJ 1679 The Unique MST 【最小生成树/次小生成树模板】

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 22668   Accepted: 8038 D ...

  8. (poj)1679 The Unique MST 求最小生成树是否唯一 (求次小生成树与最小生成树是否一样)

    Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definit ...

  9. poj 1679 The Unique MST 【次小生成树】【模板】

    题目:poj 1679 The Unique MST 题意:给你一颗树,让你求最小生成树和次小生成树值是否相等. 分析:这个题目关键在于求解次小生成树. 方法是,依次枚举不在最小生成树上的边,然后加入 ...

  10. POJ 1679 The Unique MST(判断最小生成树是否唯一)

    题目链接: http://poj.org/problem?id=1679 Description Given a connected undirected graph, tell if its min ...

随机推荐

  1. C++模板类与Qt信号槽混用

    一.正文 目前正在做一个视频处理相关的项目.项目的技术栈是这样的,UI层采用Qt来实现基本的数据展示和交互,底层音视频采用的是一套基于FFmpeg的视频处理框架.这是一套类似Microsoft Med ...

  2. 1-1 maven 学习笔记(1-6章)

    一.基础概念 1.Maven作为Apache组织中颇为成功的开源项目,主要服务于基于Java平台的项目构建,依赖管理和项目信息管理.从清理,编译,测试到生成报告,到打包部署,自动化构建过程. 还可以跨 ...

  3. [模拟赛] T3 最优序列

    Description 给出一个长度为n(n<=1000)的正整数序列,求一个子序列,使得原序列中任意长度为m的子串中被选出的元素不超过k(k<=m<=10)个,并且选出的元素之和最 ...

  4. java 打印近似圆

    只要给定不同半径,圆的大小就会随之发生改变近似圆如图 设半径为r,圆心为(r,r). 由勾股定理 易得y = r -√(2*r*x-x*x) 此处注意x+=2.因为打印窗口上一行2个字节的宽度与一列的 ...

  5. selenium + robotframework的运行原理

    1.点击ride界面启动用例执行时,首先会调用脚本 2.打开pybot脚本查看内容. 3.打开robot包下面的run文件,我们可以看到信息 run文件内容 程序启动的入口, sys.agv所表达的含 ...

  6. NEO从入门到开窗(4) - NEO CLI

    一.唠叨两句 首先,我们都知道区块链是去中心化的,其中节点都是对等节点,每个节点都几乎有完整的区块链特性,CLI就是NEO的一个命令行对等节点,当然也有GUI这个项目,图形化的NEO节点.节点之间需要 ...

  7. Java基础学习笔记六 Java基础语法之类和ArrayList

    引用数据类型 引用数据类型分类,提到引用数据类型(类),其实我们对它并不陌生,如使用过的Scanner类.Random类.我们可以把类的类型为两种: 第一种,Java为我们提供好的类,如Scanner ...

  8. 【备忘】Idea的那些事

    说到Java的IDE,似乎eclipse和Idea是目前的主流.然而,OO的课程组却一直在推荐使用eclipse,于是很多人就这样错过了Idea这样强大的IDE工具.本文将会对于Idea和Idea的一 ...

  9. pip安装selenium报错:Read timed out

    今天打算把selenium降级重新安装,发现安装时总是失败,报如下错误: raise ReadTimeoutError(self._pool, None, 'Read timed out.') pip ...

  10. C语言的第一次作业

    一.PTA实验作业 题目1. 温度转换 本题要求编写程序,计算华氏温度150°F对应的摄氏温度.计算公式:C=5×(F−32)/9,式中:C表示摄氏温度,F表示华氏温度,输出数据要求为整型. 1.实验 ...