poj 1679 求最小生成树的值是否唯一
2012-06-25 02:03
337 查看
题目大意:求最小生成树的值是否唯一,唯一输出这个值,不唯一则输出Not Unique!
解题思路:先求出最小生成树,保存最小生成树的路径,然后按边的大小由小到大枚举每条没有加入最小生成树的边比如是(u,v),在已经形成的最小生成树种,取u到v路径上最大的边的权值,比较(u,v)的这个最大权值的大小,如果相等,说明最小生成树不唯一,如果不相等,说明唯一。
解题思路:先求出最小生成树,保存最小生成树的路径,然后按边的大小由小到大枚举每条没有加入最小生成树的边比如是(u,v),在已经形成的最小生成树种,取u到v路径上最大的边的权值,比较(u,v)的这个最大权值的大小,如果相等,说明最小生成树不唯一,如果不相等,说明唯一。
#include <iostream> #include <cstdio> #include <vector> #include <queue> #include <cstring> using namespace std; #define MAX_N 101 struct edge { int u, v; int weight; inline bool operator < (const edge & b) const { return weight > b.weight; } }; struct node { int v; int w; }; priority_queue<edge> heap; priority_queue<edge> saveheap; int pre[MAX_N], parent[MAX_N], value[MAX_N], total, m, n; bool visited[MAX_N]; void Krukstral(); int FindSet(int a); bool UnionSet(int a, int b); bool solve(); int main() { int t; scanf("%d",&t); while((t--) != 0) { while(!heap.empty()) heap.pop(); while(!saveheap.empty()) saveheap.pop(); total = 0; memset(value, -1, sizeof(value)); memset(pre, -1, sizeof(pre)); memset(parent, -1, sizeof(parent)); scanf("%d %d", &n, &m); for(int i = 0; i < n; i++) { pre[i] = i; } for(int i = 0; i < m; i++) { int xi, yi, wi; scanf("%d %d %d", &xi, &yi, &wi); xi--; yi--; if(xi > yi) { xi ^= yi; yi ^= xi; xi ^= yi; } edge te; te.u = xi; te.v = yi; te.weight = wi; heap.push(te); } Krukstral(); if(!solve()) printf("Not Unique!\n"); else printf("%d\n", total); } return 0; } void Krukstral() { int num = 0; while(!heap.empty()) { edge te = heap.top(); heap.pop(); if(!UnionSet(te.u, te.v)) { num++; parent[te.v] = te.u; value[te.v] = te.weight; total += te.weight; } else saveheap.push(te); if(num == n - 1) break; } } int FindSet(int a) { if(pre[a] != a) pre[a] = FindSet(pre[a]); return pre[a]; } bool UnionSet(int a, int b) { int x, y; bool flag = true; x = FindSet(a); y = FindSet(b); if(x != y) { pre[y] = x; flag = false; } return flag; } bool solve() { edge te; while(!saveheap.empty()) //处理那些之前加入最小生成树时属于同一个集合不能加入的边 { te = saveheap.top(); saveheap.pop(); int maxVal = -1; int end = te.v; //找出u到v最小生成树中路径的最大值。 while(end != te.u && end != -1) { if(maxVal < value[end]) maxVal = value[end]; end = parent[end]; } if(end != te.u) { end = te.u; while(end != te.v && end != -1) { if(maxVal < value[end]) maxVal = value[end]; end = parent[end]; } } if(maxVal >= te.weight) return false; } while(!heap.empty()) //处理剩下的没加入的边 { te = heap.top(); heap.pop(); int maxVal = -1; int end = te.v; while(end != te.u && end != -1) { if(maxVal < value[end]) maxVal = value[end]; end = parent[end]; } if(end != te.u) { end = te.u; while(end != te.v && end != -1) { if(maxVal < value[end]) maxVal = value[end]; end = parent[end]; } } if(maxVal >= te.weight) return false; } return true; }
相关文章推荐
- POJ 1679 The Unique MST(求最小生成树是否唯一)
- POJ 1679 The Unique MST(判断最小生成树是否唯一)
- poj 1679 The Unique MST (判断最小生成树是否唯一)
- poj 1679 判断最小生成树是否唯一
- POJ_1679 最小生成树是否唯一
- poj 1679 The Unique MST(判断最小生成树是否唯一)
- POJ 1679 最小生成树是否唯一 次小生成树
- poj1679 The Unique MST ——判断最小生成树是否唯一_kruscal算法
- POJ 1679 The Unique MST(判断最小生成树是否唯一)
- poj 1679 The Unique MST 判断最小生成树是否唯一 解题报告
- poj 1679 判断最小生成树是否唯一
- POJ 1679 The Unique MST (prim判断最小生成树是否唯一)
- POJ 1679-The Unique MST(最小生成树是否唯一)
- POJ 1679 判断最小生成树是否唯一
- poj 1679 判断最小生成树是否唯一
- 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 判断最小生成树是否唯一(图论)