题目链接在这里
题目大意:
有n个点,下面有n - 1行,每行有一个编号X有一个数字m代表点X和m个其它点相连,然后后面有m个点以及权值。求最小生成树。
思路:
最小生成树,莽就完事了。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <functional>
#define clr(x) memset(x, 0, sizeof(x))
#define rep(i, n) for(int i = 0; i < n; ++i)
using namespace std;
const int MaxN = 30;
struct Node{
int x, y, val;
bool operator > (const Node &x) const{
return val > x.val;
}
};
int n;
int par[MaxN], r[MaxN];
int Find(int x){
if(x == par[x]) return x;
return par[x] = Find(par[x]);
}
void unite(int x, int y){
x = Find(x);
y = Find(y);
if(x == y) return;
if(r[x] < r[y]) par[x] = y;
else{
par[y] = x;
if(r[x] == r[y]) ++r[x];
}
}
void init(){
rep(i, MaxN) par[i] = i;
clr(r);
}
bool check(int x, int y){
return Find(x) == Find(y);
}
int main(){
priority_queue<Node, vector<Node>, greater<Node> > que;
while(cin >> n && n){
while(!que.empty()) que.pop();
init();
char x, y;
int m, dis;
for(int i = 1; i < n; ++i){
cin >> x >> m;
int xx = x - 'A';
rep(i, m){
cin >> y >> dis;
int yy = y - 'A';
que.push(Node{xx, yy, dis});
}
}
int ans = 0;
while(--n){
Node node = que.top();
que.pop();
if(check(node.x, node.y)){
++n;
continue;
}
//cout << "x:" << node.x << "\ty:" << node.y << "\tval:" << node.val << endl;
unite(node.x, node.y);
ans += node.val;
}
cout << ans << endl;
}
return 0;
}