1003. Emergency (25)

题目链接:https://www.patest.cn/contests/pat-a-practise/1003


题目大意: 给一个图,求所给两点之间的最短路径的条数,以及这些最短路径中,哪条路径经过的所有节点的权值和最大。


解题思路:使用Dijkstra最短路径算法。

  • edge[i][j]:表示i到j的距离

  • weight[i]:表示节点i的权值

  • dist[i]:表示从所给的起点到i点的最短路径

  • wi[i]:表示从所给的起点到i点的最大权值和

  • pathcnt[i]:表示从所给的起点到i点的最短路径条数


代码如下

#include <iostream>
#include <algorithm>
using namespace std;
const int inf=100000000;
int edge[501][501];//元素值为边距离
int weight[501];//城市救援队数
int dist[501];//dist[i]为从出发点到i点的最短路径长度
int wi[501];//出发点到i点的救援队总数
int pathcnt[501];//最短路径的条数
int main(int argc, char const *argv[])
{   
    int n,m,c1,c2;
    cin>>n>>m>>c1>>c2;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            edge[i][j]=inf;//初始化边的距离
    for(int i=0;i<n;i++){
        cin>>weight[i];//输入节点权值
        dist[i]=inf;//最短距离初始化
    }
    int src,des,dis;
    for(int i=0;i<m;i++){
        cin>>src>>des>>dis;//输入每条边
        edge[src][des]=dis;
        edge[des][src]=dis;
    }
    dist[c1]=0;
    wi[c1]=weight[c1];
    pathcnt[c1]=1;
    int visit[501]={0};
    /*使用dijkstra算法求出c1到每个点的最短路径*/
    for(int i=0;i<n;i++){
        int current=-1,min=inf;
        /*先找当前距离c1点的最短距离,
        以及最短路径上的终点*/
        for(int j=0;j<n;j++){
            if(visit[j]==0&&dist[j]<min){
                current=j;
                min=dist[j];
            }
        }
        if(current==-1) 
            break;
        visit[current]=1;
        /*向外扩张,更新最短距离*/
        for(int j=0;j<n;j++){
            if(visit[j]==0&&edge[current][j]!=inf){//当前节点为曾访问,且可达current
                if(dist[current]+edge[current][j]<dist[j]){//找到更短的路径
                    dist[j]=dist[current]+edge[current][j];//更新路径
                    wi[j]=wi[current]+weight[j];//更新节点权值和
                    pathcnt[j]=pathcnt[current];//更新路径数量
                }
                else if(dist[current]+edge[current][j]==dist[j]){//相同路径相同
                    pathcnt[j]=pathcnt[current]+pathcnt[j];//更新路径数量
                    if(wi[j]<wi[current]+weight[j])//更新总节点权值
                        wi[j]=wi[current]+weight[j];
                }
            }
        }
    }
    cout<<pathcnt[c2]<<" "<<wi[c2]<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值