http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3367
#include <iostream> #include <algorithm> #include <limits> #include <queue> using namespace std; const int MAXN = 105, INF = numeric_limits<int>::max(); typedef pair<int, int> PII; typedef vector<PII> VPII; int parent[MAXN]; int T, n, tot; int Find(int x)//finds the subset of the x-th element and { //updates its predecessors for furture efficiency return (parent[x] == x) ? x : parent[x] = Find(parent[x]); } void Union(int x, int y)//units two subsets in to a single subset, { //called when they should share the same parent parent[Find(x)] = Find(y); } struct Edge { int from, to, cost; Edge() {}; Edge(int f, int t, int c) :from(f), to(t), cost(c) { }; friend bool operator<(const Edge &e, const Edge &f) { if (e.cost != f.cost)return e.cost<f.cost; if (e.from != f.from)return e.from<f.from; return e.to<f.to; }; } edge[MAXN*MAXN / 2]; struct cmp { bool operator()(const PII & x, const PII & y) { if (x.first != y.first)return x.first>y.first; return x.second>y.second; } }; priority_queue<PII, VPII, cmp> Q; bool Kruskal() { /**initialization*/ for (int i = 1; i <= n; i++) //the index of an element represents the subset it belongs to, parent[i] = i; //so initially itself while (!Q.empty())Q.pop(); sort(edge, edge + tot); int counter = 0; for (int i = 0; i<tot; i++) { int u = Find(edge[i].from), v = Find(edge[i].to); if (u != v) { Q.push(make_pair(edge[i].from, edge[i].to)); parent[u] = v; counter++; } } if (counter == n - 1) return true; return false; } int main() { cin >> T; while (T--) { tot = 0; cin >> n; /**add edges*/ int t; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { scanf("%d", &t); if (i<j&&t)edge[tot++] = Edge(i, j, t); } /**Kruskal*/ if (Kruskal()) { bool f = true; while (!Q.empty()) { auto tmp = Q.top(); if (f)f = false; else cout << ‘ ‘; printf("%d %d", tmp.first, tmp.second); Q.pop(); } printf("\n"); } else printf("-1\n"); } return 0; }
时间: 2024-11-10 08:20:22