Description
Input
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!
#include <iostream> #include <queue> #include <algorithm> #include <cstring> #include <cmath> #include <iomanip> using namespace std; struct Edge{ int u, v, w; }edges[10010]; int t, n, m, mst, cnt, flag; int father[110], path[10010]; void makeSet(){ for (int i = 1; i <= n; i++) father[i] = i; } int findSet(int x){ if (father[x] != x) father[x] = findSet(father[x]); return father[x]; } int cmp(Edge a, Edge b) { return a.w < b.w; } void Kruskal(){ //true则表示mst不唯一; makeSet(); sort(edges,edges + m, cmp); cnt = 0; mst = 0; for (int i = 0; i < m; i++) { int u = findSet(edges[i].u); int v = findSet(edges[i].v); if (u != v) { father[u] = v; path[cnt++] = i; //记录路径; mst += edges[i].w; //最小生成树的总权值; } } for (int k = 0; k < cnt; k++) { //枚举去掉每一条边; makeSet(); int sum = 0; //sum用于记录新的生成树的总权值; int j = 0; //j用于记录新生成树的边的数量; for (int i = 0; i < m; i++) { if (i == path[k]) //不使用这一条边; continue; int u = findSet(edges[i].u); int v = findSet(edges[i].v); if (u != v) { father[u] = v; sum += edges[i].w; j++; } } if (j == n - 1 && sum == mst) { //能构成树,且为最小生成树; flag = 0; return; } } } int main(){ cin >> t; while (t--) { cin >> n >> m; for (int i = 0; i < m; i++) { cin >> edges[i].u >> edges[i].v >> edges[i].w; } flag = 1; Kruskal(); if (flag) cout << mst << endl; else cout << "Not Unique!" << endl; } return 0; }