题目链接:

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. 冒泡排序及优化(Java实现)

    向大端冒泡 public class BubbleSort { public static <T extends Comparable<? super T>> void sor ...

  2. Mycat 分片规则详解--数据迁移及节点扩容

    使用的是 Mycat 提供的 dataMigrate 脚本进行对数据进行迁移和节点扩容,目前支持的 Mycat 是1.6 版本,由于 Mycat 是由 Java 编写的因此在做数据迁移及节点扩容时需要 ...

  3. NodeJs实现下载Excel文件

    nodejs作为一门新的语言,报表功能也不是十分完善. (1).js-xlsx : 目前 Github 上 star 数量最多的处理 Excel 的库,支持解析多种格式表格XLSX / XLSM / ...

  4. 【BootStrap】 布局组件 II

    BootStrap 布局组件 II ■ 分页 BS中通过.pagination的ul元素来实现一个分页集合,一个典型的分页如下: <ul class="pagination" ...

  5. 【Python】 用户图形界面GUI wxpython III 更多组件

    wxpython - 更多组件 我写到的这些组件可能一来不是很详细,二来不是最全的,想要更好地用这些组件,应该还是去看看教程和别的示例.比较简单的,推荐http://download.csdn.net ...

  6. 数据库 --> sqlite3总结

    Sqlite3总结 SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中. sqlite语句 #sqlite3 test.db //设置宽度为2sqlit ...

  7. selenium2自动化测试学习笔记(五)-参数化编程,自动登陆网易QQ邮箱

    学习python下使用selenium2自动测试第6天,参数化编程这节课花了两天时间. 本次编程主要时间是花在熟悉python上 知识点or坑点: 1.读取txt.xml.csv等文件存储的账号.密码 ...

  8. Kaggle竞赛 —— 房价预测 (House Prices)

    完整代码见kaggle kernel 或 Github 比赛页面:https://www.kaggle.com/c/house-prices-advanced-regression-technique ...

  9. JavaEE Servlet 核心方法及生命周期

    做JavaWeb开发,免不了要和Servlet打交道.Servlet是Sun(Oracle)官方定义的一个Web开发规范,所有Servlet开发都必须遵守.自己以前也没有从头做过Web开发,所以这方面 ...

  10. 工作流Activiti5.13学习笔记(一)

    了解工作流 1.工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档.信息或任务的过程自动进行,从而实现某 ...