Description
Input
Output
Sample Input
9 A 2 B 12 I 25 B 3 C 10 H 40 I 8 C 2 D 18 G 55 D 1 E 44 E 2 F 60 G 38 F 0 G 1 H 35 H 1 I 35 3 A 2 B 10 C 40 B 1 C 20 0
Sample Output
216 30
题意:求丛林中所有点都连通时所需的最小花费,即构造最小生成树。
思路:用 Kruskal 或 prim 算法构造最小生成树(将字符处理成字符串输入)
代码如下:
Kruskal:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> int flag[100], n; struct node { int s, d, c; }road[100]; bool cmp(const node& a, const node& b) { return a.c<b.c; } void init() { for(int i=0; i<n; i++)//下标从0 开始 flag[i]=i; //初始化根节点为其本身下标 } int find(int x)//找该点所属的集合的根节点 { return x==flag[x] ? x : flag[x]=find(flag[x]); } using namespace std; int main() { #ifdef OFFLINE freopen("t.txt","r",stdin); #endif int i, j, k, p, w; char s[3], d[3]; while(scanf("%d", &n)){ if(n==0) break; j=n-1; p=0; while(j--){ scanf("%s %d", s, &k); while(k--){ scanf("%s %d", d, &w); road[p].s=s[0]-'A'; road[p].d=d[0]-'A'; road[p++].c=w; } } sort(road, road+p, cmp); init(); int num=0, cost=0; for(i=0;i<p;i++){ int L=find(road[i].s), R=find(road[i].d); if(L != R){ num++; flag[L]=R; cost+=road[i].c; } if(num==n-1) break; } printf("%d\n", cost); } return 0; }
prim:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define INF 0x3f3f3f3f int nearvex[300], lowest[300], road[300][300], n; int prim(int u) { int i, j, k, min, cost=0; for(i=0;i<n;i++){//顶点下标从0开始 lowest[i]=road[u][i]; nearvex[i]=u;//距离i的前一节点 } nearvex[u]=-1;//-1表示已经该点已加入的最小生成树 for(i=1;i<n;i++){//再加 (n-1) 个点(每次在未加入最小生成树的点集中找距离树点集的最小值) min=INF, k=-1; for(j=0;j<n;j++){ if(nearvex[j] != -1&&lowest[j]<min){ min=lowest[j]; k=j; } } if(k != -1){ nearvex[k]=-1; cost+=lowest[k]; for(j=0;j<n;j++){ if(nearvex[j] != -1&&road[k][j]<lowest[j]) lowest[j]=road[k][j];//从k出发更新最小值 } } } return cost; } using namespace std; int main() { #ifdef OFFLINE freopen("t.txt","r",stdin); #endif int k, t, w; char u[3], v[3]; while(scanf("%d", &n)){ if(n==0) break; memset(road, INF, sizeof(road)); k=n-1; while(k--){ scanf("%s %d", u, &t);//将字符当成字符串读入 while(t--){ scanf("%s %d", v, &w); road[u[0]-'A'][v[0]-'A']=w;//无向路(2条) road[v[0]-'A'][u[0]-'A']=w; } } int ans=prim(0); printf("%d\n", ans); } return 0; }