题意:
有n个村庄由一些道路连接,每条道路有维护成本,求任意村庄两两相连时所需的最小维护成本。
input
输入包括多组数据,最多100组,最后以输入0表示结束。
对于每一组数据,第一行一个n,表示景区数量。1<n<27
之后n-1行,每行第一个是一个大写字母,表示当前村庄的编号,接着是k,表示当前景区对外可以有k中线路制造方式,接着k对,每对第一个是一个字母,表示这条路线连接的村庄,第二个是一个数字,表示制造成本。0<=k<=15。最多75条制造线路,每条线路的制造成本最大是100。
Output
对于每一组数据,输出一行表示最小成本。
kruskal算法
#include<iostream>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1e3+ 5;
int head[maxn], vi[maxn], weight[maxn], next[maxn];
int cnt, dis[maxn], vis[maxn];
void add(int u, int v, int w){
vi[++cnt] = v;
weight[cnt] = w;
next[cnt] = head[u];
head[u] = cnt;
}
int kruskal(int n){
int k;
for(int i = 1; i <= n; i++)
dis[i] = inf, vis[i] = 0;
for(int i = 0; i <= n; i++){
k = - 1;
for(int j = 1; j <= n; j++)
if(!vis[j] && (dis[j] < dis[k] || k == -1)) k = j;
if(k == - 1) break;
vis[k] = 1;
if(i == 0) dis[k] = 0;
for(int j = head[k]; j; j = next[j])
if(weight[j] < dis[vi[j]] && !vis[vi[j]]) dis[vi[j]] = weight[j];
}
int ans = 0;
for(int i = 1; i <= n; i++)
ans += dis[i];
return ans;
}
int main(){
ios::sync_with_stdio(false);
int n, u, v, w, k;
char ch;
while(cin>>n){
if(n == 0) break;
cnt = 0;
for(int i = 1; i <= n; i++)
head[i] = 0;
for(int i = 1; i < n; i++){
cin >> ch >> k;
u = ch - 'A' + 1;
for(int j = 0; j < k; j++){
cin >> ch >> w;
v = ch - 'A' + 1;
add(u, v, w);
add(v, u, w);
}
}
cout << kruskal(n) <<endl;
}
}
prim算法
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1e3 + 5;
struct node{
int u, v, w;
}edge[maxn];
bool cmp(node a, node b){
return a.w < b.w;
}
int f[maxn];
int find(int x){
return x == f[x] ? x : (f[x] = find(f[x]));
}
int main(){
ios::sync_with_stdio(false);
int cnt;
int n, k, u, v, w;
char ch;
while(cin >> n){
if(n == 0) break;
for(int i = 0; i <= n; i++) f[i] = i;
cnt = 0;
for(int i = 1; i < n; i++){
cin >> ch >> k;
u = ch - 'A' + 1;
while(k--){
cin >> ch >> w;
v = ch - 'A' + 1;
edge[++cnt].u = u;
edge[cnt].v = v;
edge[cnt].w = w;
}
}
sort(edge + 1, edge + 1 + cnt, cmp);
int ans = 0;
int cot = 0;
for(int i = 1; i <= cnt; i++)
{
int fu = find(edge[i].u);
int fv = find(edge[i].v);
if(fu != fv) {
ans += edge[i].w;
f[fu] = fv;
cot++;
}
if(cot == n - 1) break;
}
cout << ans <<endl;
}
return 0;
}