题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1301
题意:给N个村庄,然后n-1行输入,每行是村庄编号、与它连接的村庄数,然后是每个与它连接的村庄的距离。
求最小生成树。
Prim:贪心思想,假设在某步已经找到了最小生成树的一部分G,dis记录了其它每点到G中最短的距离,pre记录最短距离对于的G中连接点,从所有dis中找出最短的,将其加入到G中,再更新dis和pre...
要注意的是scanf读取字符,如果键盘输入3换行(或者空格),
scanf("%d",&num);只会读取3不会去掉换行符或空格符,需要getchar()去掉或者刷新缓冲区。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define INF 0xffffff
using namespace std;
int Map[30][30];//图
int pre[30];
int dis[30];//
int n;
int Prim() {
int ret = 0;
for(int i = 1; i <= n;i++) {
pre[i] = 1;
dis[i] = Map[i][1];
}
for(int i = 1;i < n;i++) {
int Min = INF;
int num;
for(int j = 1;j <= n;j++) {
if(dis[j] == 0)
continue;
if(dis[j] < Min) {
Min = dis[j];
num = j;
}
}
if(Min == INF)
break;
ret += dis[num];
dis[num] = 0;
pre[num] = num;
for(int j = 1;j <= n;j++) {
if(dis[j] != 0 && dis[j] > Map[j][num])
dis[j] = Map[j][num];
pre[j] = num;
}
}
return ret;
}
int main()
{
while(scanf("%d",&n) != EOF && n != 0) {
getchar();//取出换行符
for(int i = 0;i < 30;i++)
for(int j = 0;j < 30;j++) {
Map[i][j] = INF;
if(i == j)
Map[i][j] = Map[j][i] = 0;
}
char temp;
int a;//输入的点
int num;//点个数
for(int i = 1;i < n;i++) {
scanf("%c",&temp);
a = temp - 'A' + 1;
int b;
int length;
scanf("%d",&num);
getchar();
for(int i = 0;i < num;i++) {
scanf("%c",&temp);
b = temp - 'A' + 1;
scanf("%d",&length);
getchar();
Map[a][b] = Map[b][a] = length;
}
}
printf("%d\n",Prim());
}
return 0;
}