HDOJ1301 Jungle Roads----Prim

题目链接 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; 
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值