//INPUT这块给我看的头大,意思为先给一个N,之后有N-1行。每行第一字符代表村庄,第二个数字表示此村庄 //与几个村庄相通(有路)。 //eg:A 2 B 12 I 25为与A相连的有两条路,一条通向B,权值为12,另一条通向I,权值为25 #include "stdio.h" #include "string" #include "queue" using namespace std; struct Edge{ int x;int y; int weight; }; priority_queue<Edge> myPQueue; int Father[1000]; int height[1000]; void Init(int N){ while (!myPQueue.empty()) myPQueue.pop(); for (int i = 0; i < N; ++i) { Father[i] = i; height[i] = 1; } } bool operator < (Edge lhs,Edge rhs){ return lhs.weight > rhs.weight; } int find(int x){ if (x != Father[x]){ Father[x] = find(Father[x]); return Father[x]; } return x; } void Union(Edge edge1){ int x = edge1.x; int y = edge1.y; int x_father = find(x); int y_father = find(y); if(height[x_father] > height[y_father]){ Father[y_father] = x_father; } else if (height[x_father] < height[y_father]){ Father[x_father] = y_father; } else{ Father[y_father] = x_father; height[x_father]++; } } int KrusKal(int N){ int sum = 0; int count = 0; while (!myPQueue.empty()){ if (count == N-1) break; Edge edge = myPQueue.top(); myPQueue.pop(); int city1 = edge.x,city2 = edge.y; if (find(city1) != find(city2)){ Union(edge); ++count; sum += edge.weight; } } return sum; } int main(){ int N; while (scanf("%d",&N)!=EOF){ getchar(); if (N == 0) break; Init(N);//初始化优先队列 for (int i = 0; i < N-1; ++i) { char city1,city2; scanf("%c",&city1); int count,weight; scanf("%d ",&count); for (int j = 0; j < count; ++j) { scanf("%c",&city2); scanf("%d ",&weight); Edge edge; edge.x = city1-'A';edge.y = city2-'A'; edge.weight = weight; myPQueue.push(edge); } }//已将所有的边入队 printf("%d\n",KrusKal(N)); } }