toj 3073 Country Road

题目链接:http://acm.tju.edu.cn/toj/showp3073.html

题目大意:修路,要求任意两点之间都能到达,且花费最小,有的路已经修好了,求最小花费。

思路:很明显的MST问题  prim可解。注意两点:1、修好的路 权值设为0即可; 2、初始化时,点与点之间的距离设为无穷大,这里的无穷大只要比权值最大值大就行了,点到自身的距离设为0。(我就是因为一开始无穷大设的 0x7f ,一直wrong,不明觉厉,偶然改成1010就对了- -!)

顺便复习下prim吧:每次选取当前点到下一点距离最小的加入进来即可。唉,我表达的不太清楚,给个链接:http://blog.chinaunix.net/uid-25324849-id-2182922.html

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <limits.h>
using namespace std;
const int MAXN = 1003;
const int INF = 1010;
int n;
int visited[MAXN], dist[MAXN];
int map[MAXN][MAXN];


prim  模板
int prim()
{
    int i,j,min, pos, sum;                   
    for(i=1;i<=n;i++)      //dist[]表示从相邻点到它的距离,初始化为从起点到各点的距离。
    dist[i] = map[1][i];
    
    visited[1] = 1;
    
    for(i=0;i<n-1;i++)  //小于n或n-1都可以 因为1已经放进去了 所以至少还要放n-1次
    {
       min = INF;
       for(j=1;j<=n;j++)
       if(!visited[j] && dist[j]<min)     //找出下一步中距离最小的点。
       {
          min = dist[j];
          pos = j;
       }
       visited[pos]=1;
       for(j=1;j<=n;j++)                     //更新所有dist[]
        if(!visited[j] && map[pos][j]<dist[j])
          dist[j] = map[pos][j];
    }
    sum = 0;
    for(i=1;i<=n;i++){                    //若最后dist有无穷大,说明没有连通
       sum+=dist[i];
       if(dist[i]==INF) return -1;
    }
    return sum;
}


int main()
{
    int cas,i,j,m,k,s,t,d;
    cin>>cas;
    while(cas--)
    {
         cin>>n>>m>>k;
         memset(visited,0,sizeof(visited));
        
         for(i=1;i<=n;i++)      //初始化map
           for(j=1;j<=n;j++){
              if(i==j) map[i][j]=0;
              else map[i][j]=INF;
           }
           
        for(i=0;i<m;i++)
        {
           cin>>s>>t;
           map[s][t] = map[t][s] = 0;       //无向图 要双向赋值
        }
        for(i=0;i<k;i++)
        {
           cin>>s>>t>>d;
           map[s][t] = map[t][s] = d;     //无向图  要双向赋值
        }        
        cout<<prim()<<endl;
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值