Poj 1679 The Unique MST
2012-08-18 14:07
267 查看
题目描述:
给定一个连通无向网,判定它的最小生成树是否唯一。
输入描述:
输入文件的第1 行为一个整数t,1≤t≤20,表示测试数据的数目。每个测试数据描述了一个
连通无向网。每个测试数据的第1 行为两个整数:n 和m,1≤n≤100,分别表示顶点的数目和
边的数目。接下来有m 行,每行为一个三元组(xi, yi, wi),表示一条边(xi, yi),xi 和yi 表示边的两
个顶点,顶点序号从1 开始计起,这条边的权值为wi。任何两个顶点间最多只有一条边。
输出描述:
对输入文件中的每个测试数据,如果最小生成树是唯一的,则输出最小生成树的权;如果最
小生成树不唯一,则输出"Not Unique!"。
模版判断是否是唯一的最小生成树。这里借鉴一下:
判定最小生成树是否唯一的一个正确思路为:
1) 对图中每条边,扫描其他边,如果存在相同权值的边,则对该边作标记;
2) 然后用Kruskal 算法(或Prim 算法)求MST;
3) 求得MST 后,如果该MST 中未包含作了标记的边,即可判定MST 唯一;如果包含作了
标记的边,则依次去掉这些边再求MST,如果求得的MST 权值和原MST 的权值相同,即可判定
MST 不唯一。
so~~~~
给定一个连通无向网,判定它的最小生成树是否唯一。
输入描述:
输入文件的第1 行为一个整数t,1≤t≤20,表示测试数据的数目。每个测试数据描述了一个
连通无向网。每个测试数据的第1 行为两个整数:n 和m,1≤n≤100,分别表示顶点的数目和
边的数目。接下来有m 行,每行为一个三元组(xi, yi, wi),表示一条边(xi, yi),xi 和yi 表示边的两
个顶点,顶点序号从1 开始计起,这条边的权值为wi。任何两个顶点间最多只有一条边。
输出描述:
对输入文件中的每个测试数据,如果最小生成树是唯一的,则输出最小生成树的权;如果最
小生成树不唯一,则输出"Not Unique!"。
模版判断是否是唯一的最小生成树。这里借鉴一下:
判定最小生成树是否唯一的一个正确思路为:
1) 对图中每条边,扫描其他边,如果存在相同权值的边,则对该边作标记;
2) 然后用Kruskal 算法(或Prim 算法)求MST;
3) 求得MST 后,如果该MST 中未包含作了标记的边,即可判定MST 唯一;如果包含作了
标记的边,则依次去掉这些边再求MST,如果求得的MST 权值和原MST 的权值相同,即可判定
MST 不唯一。
so~~~~
#include <iostream> #include <algorithm> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #define MAX 10500 #define INF 0x7FFFFFFF # define eps 1e-5 using namespace std; struct Edge//边的信息:起点 终点 权值 是否访问 是否删去 是否存在权值相等 { int s,e,value; int vis,del,equal; } edge[MAX]; int n,m,par[105]; int mst;//第一次mst的标志 int find(int x)//查 { while(par[x] != x) x = par[x]; return x; } void connect(int a,int b)//并 { if(a < b) par[b] = a; else par[a] = b; } bool cmp(Edge a, Edge b)//比 { return a.value < b.value; } int kruskal() { int i,j,sum = 0; for(i=1; i<=n; i++) par[i] = i; for(i=1; i<=m; i++) { int a = find(edge[i].s); int b = find(edge[i].e); if(!edge[i].del && a != b) { connect(a,b); sum += edge[i].value; if(mst == 1) { edge[i].vis = 1; } } } return sum ; } int main() { int t,i,j; scanf("%d",&t); while(t --) { scanf("%d%d",&n,&m); for(i=1; i<=m; i++)//初始化以及构图 { scanf("%d%d%d",&edge[i].s,&edge[i].e,&edge[i].value); edge[i].del = 0; edge[i].vis = 0; edge[i].equal = 0; } for(i=1; i<=m; i++)//找出有相等权值的边 for(j=1; j<=m; j++) { if(i != j && edge[i].value == edge[j].value) { edge[i].equal = 1; } } sort(edge+1,edge+1+m,cmp); mst = 1; int sum1 = kruskal(); int ok = 1;//作为是否mst不唯一的标志 mst = 0; for(i=1; i<=m; i++) { if(edge[i].vis && edge[i].equal ) { edge[i].del = 1;//依次去掉权值相等的边,再求mst int sum2 = kruskal(); if(sum2 == sum1)//两次权值相等 { printf("Not Unique!\n"); ok = 0; break; } edge[i].del = 0;//删去的边补回来 } } if(ok == 1) { printf("%d\n",sum1); } } return 0; }
相关文章推荐
- POJ 1679 The Unique MST 次小生成树模板题
- POJ - 1679 The Unique MST(次小生成树)
- POJ1679 The Unique MST 【次小生成树】
- poj 1679 The Unique MST 【次小生成树+100的小数据量】
- poj--1679--The Unique MST(次小生成树)
- POJ 1679 The Unique MST
- poj 1679: The Unique MST【次小生成树】
- poj 1679 The Unique MST(最小树不唯一的判定)
- POJ 1679 The Unique MST
- POJ 1679:The Unique MST(次小生成树&&Kruskal)
- poj 1679 The Unique MST
- POJ--1679--The Unique MST【推断MST是否唯一】
- POJ 1679 The Unique MST(次小生成树)
- POJ 1679 The Unique MST(次小生成树之一)
- poj 1679 The Unique MST
- Poj 1679 The Unique MST(次小生成树)
- POJ 1679 The Unique MST (次小生成树)
- POJ 1679 The Unique MST (次小生成树)
- POJ 1679 The Unique MST(最小生成树)
- POJ 1679:The Unique MST(次小生成树&&Kruskal)