L2-001 紧急救援分数 25

输入样例:

4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2

输出样例:

2 60
0 1 3

#include<iostream>
using namespace std;
const int N=550;
const int INF=1e9+7;
int n,m,s,d;
//输入数据
int nums[N];//城市救援队的数目
int sf[550][550];//存储城市道路
       //需要更新的数据
//求解数据
int cnt[550];//起始点到该节点的最短路径数目
int maxn[550];//起始点到该节点的召集的救援队最大数目
//辅助求解
int way[550];//存储最短路径,每个节点前面的节点(方便从终点递归求解)
int flag[550];//标记该城市已经被走过
int mins[550];//起始点到该节点的最短路径长度

void dijistra(){
    //起点的初始化 s
   
   // flag[s]=1; //这里不能初始化
  //  way[s]=s;
    cnt[s]=1;
    maxn[s]=nums[s];

    //从起始点开始更新节点
    for(int i=0;i<n;i++){//和起始点的边
        mins[i]=sf[s][i];
    }

    while(1){
        int min_dist=INF;
        int mid=-1;
        for(int i=0;i<n;i++){//找到距离连通图的最短路径
//刚开始从起始点开始找最短路径,
            if(flag[i]==0&&mins[i]<min_dist){
                min_dist=mins[i];
                mid=i;
                
            }
        }
       
        if(mid==-1)break;
        flag[mid]=1;
        for(int i=0;i<n;i++){//更新其余节点于连通图的最短路径
          if(flag[i]==0){
              if(mins[i]>mins[mid]+sf[mid][i]){
                  mins[i]=mins[mid]+sf[mid][i];
                  cnt[i]=cnt[mid];//由mid节点连通,一条路径
                  maxn[i]=nums[i]+maxn[mid];//人员
                  way[i]=mid;
              }
              else{
               if(mins[i]==mins[mid]+sf[mid][i]){
                   cnt[i]+=cnt[mid];//相等就多路径了
                   if(maxn[i]<maxn[mid]+nums[i]){
                       maxn[i]=maxn[mid]+nums[i];
                       way[i]=mid;//选人多的一条路
                   }
                   
               }

                  
              }
          }  
            
        }
    }
    
    
}

void Print(int t){
    if(t==s){
        cout<<t; return ;
    }
    Print(way[t]);
    cout<<" "<<t;
}


int main(){
cin>>n>>m>>s>>d;
for(int i=0;i<n;i++)cin>>nums[i];
    //城市道路的初始化
for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
        if(i!=j)sf[i][j]=INF;
    }
}
    //输入城市道路
for(int i=0;i<m;i++){
    int x,y,c;cin>>x>>y>>c;
    sf[x][y]=c;sf[y][x]=c;
}
    //dijistra算法
    dijistra();
    cout<<cnt[d]<<" "<<maxn[d]<<endl;
    Print(d);
    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值