这道题就是一道很水的最小生成树的题目,一下给出Prim和Kruskal的两种代码。
两种代码都是用优先队列去实现的
Prim:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#define len 100010
using namespace std;
struct edge{
int u, v, w, nxt;
friend bool operator < (const edge &a, const edge &b){
return a.w > b.w;
}
};
edge e[len];
int head[len], hcnt = 0;
int minc = 0, n = 0;
bool vis[len];
priority_queue <edge> q;
void Init(){
memset(vis, false, sizeof (vis));
memset(head, -1, sizeof (head));
while (!q.empty()) q.pop();
hcnt = 0; minc = 0;
}
void adde(int u, int v, int w){
e[hcnt].u = u; e[hcnt].v = v; e[hcnt].w = w;
e[hcnt].nxt = head[u]; head[u] = hcnt ++;
e[hcnt].v = u; e[hcnt].u = v; e[hcnt].w = w;
e[hcnt].nxt = head[v]; head[v] = hcnt ++;
}
void prim(){
bool flag = false;
for (int i=1; i<=n; i++) {
if (!vis[i]){
flag = true; break;
}
}
if (!flag) return;
edge tmp = q.top(); q.pop();
while (!q.empty() && vis[tmp.v]){
tmp = q.top(); q.pop();
}
minc += tmp.w;
vis[tmp.v] = true;
// printf("u: %c, v: %c, w: %d\n", tmp.u-1+'A', tmp.v-1+'A', tmp.w);
for (int i=head[tmp.v]; ~i; i=e[i].nxt) q.push(e[i]);
prim();
}
int main(){
while (~scanf("%d", &n)){
if (!n) break;
Init();
for (int i=1; i<n; i++){
char ch; int num;
scanf("%c", &ch);
while (ch < 'A' || ch > 'Z') scanf("%c", &ch);
scanf("%d", &num);
int u = ch - 'A' + 1;
for (int j=1; j<=num; j++){
char c; int p;
scanf("%c", &c);
while (c < 'A' || c > 'Z') scanf("%c", &c);
scanf("%d", &p);
int v = c - 'A' + 1;
adde(u, v, p);
}
}
for (int i=head[1]; ~i; i=e[i].nxt) q.push(e[i]);
vis[1] = true;
prim();
printf("%d\n", minc);
}
return 0;
}
Kruskal:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#define len 27
using namespace std;
struct edge{
int u, v, w, nxt;
friend bool operator<(const edge& a, const edge& b){
return a.w > b.w;
}
};
edge e[100010];
int head[len], hcnt;
int n, minc;
int F[len];
priority_queue <edge> q;
void adde(int u,int v,int w){
e[hcnt].u = u; e[hcnt].v = v; e[hcnt].w = w;
e[hcnt].nxt = head[u]; q.push(e[hcnt]);
head[u] = hcnt ++;
}
void Init(){
memset(head, -1, sizeof(head));
hcnt = 0; minc = 0;
if (!q.empty()) q.pop();
for (int i=0; i<len; i++) F[i] = i;
}
int Find(int x){
if (F[x] == x)
return x;
return F[x] = Find(F[x]);
}
void Merge(int x, int y){
int _x = Find(x), _y = Find(y);
if (_x == _y) return;
else{
F[_x] = _y;
}
}
void kruskal(){
while (!q.empty()){
edge h = q.top(); q.pop();
int _x = Find(h.u), _y = Find(h.v);
if (_x != _y){
Merge(_x, _y);
minc += h.w;
}else continue;
}
}
int main(){
while (~scanf("%d", &n)){
if (n == 0) break;
Init();
for (int p=1; p<n; p++){
char ch; int num;
scanf("%c", &ch);
while (ch > 'Z' || ch < 'A') scanf("%c", &ch);
scanf("%d", &num);
for (int i=0; i<num; i++){
int w; char c;
scanf("%c", &c);
while (c > 'Z' || c < 'A') scanf("%c", &c);
scanf("%d", &w);
int v = c - 'A' + 1;
int u = ch - 'A' + 1;
adde(u, v, w);
}
}
kruskal();
printf ("%d\n", minc);
}
return 0;
}