L2-001 紧急救援 [Dijkstra]

这题是一道给我这个菜鸡复习Dijkstra的好题。

因为要求比较多,先把大致需要的数组罗列一下。

dis[]记录最短路

path[]记录路径

pnum[]记录最短路数目

cnt[]记录最多人数

vis[]记录是否走过这个点

首先需要将vis和cnt置零,dis置∞(用邻接矩记录边也要记得置∞)

接着对起始点初始化,dis[s]=0;path[s]=-1;pnum[s]=1;cnt[s]=s点人数;

从每个点开始,先遍历所有点,如果找到一个没有被访问过的并且距离更近的点,将这点作为起点,进行松弛操作

松弛操作有两种情况,一种是距离较大的情况,更新各个数组即可。如果距离相等,要将两者的pnum[]和cnt[]相加。

因为用了数组记录最短路的每个点前一个节点,所以打印路径递归即可,详见代码

#include <iostream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <math.h>
#include <queue>
#include <vector>
#define maxn 605
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int num[maxn],dis[maxn],path[maxn],pnum[maxn],vis[maxn];
int ma[maxn][maxn];
int n,m,s,d,u,v,w;
int cnt[maxn];
void dijkstra()
{
    memset(vis,0,sizeof(vis));
    memset(cnt,0,sizeof(cnt));
    for(int i=0;i<n;i++)
        dis[i]=INF;
    dis[s]=0;
    path[s]=-1;
    pnum[s]=1;
    cnt[s]=num[s];
    for(int i=0;i<n;i++)
    {
        int t,minn=INF;
        for(int j=0;j<n;j++)
        {
            if(!vis[j]&&dis[j]<minn)
            {
                t=j;
                minn=dis[j];
            }
        }
        vis[t]=1;
        for(int j=0;j<n;j++)
        {
            if(dis[j]>dis[t]+ma[t][j])
            {
                dis[j]=dis[t]+ma[t][j];
                path[j]=t;
                cnt[j]=cnt[t]+num[j];
                pnum[j]=pnum[t];
            }
            else if(dis[j]==dis[t]+ma[t][j])
            {
                pnum[j]+=pnum[t];
                if(cnt[j]<cnt[t]+num[j])
                {
                    cnt[j]=cnt[t]+num[j];
                    path[j]=t;
                }
            }
        }
    }
}
void print(int x)
{
    if(path[x]==-1)
    {
        printf("%d",x);
        return;
    }
    print(path[x]);
    printf(" %d",x);
    return;
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&d);
    memset(ma,INF,sizeof(ma));
    for(int i=0;i<n;i++)
        scanf("%d",&num[i]);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%d",&u,&v,&w);
        ma[u][v]=w;
        ma[v][u]=w;
    }
    dijkstra();
    printf("%d %d\n",pnum[d],cnt[d]);
    print(d);
    return 0;
}
View Code

 

posted on 2019-03-09 10:25  FTA_Macro  阅读(197)  评论(0编辑  收藏  举报

导航