首页 > 其他 > 详细

L2-001 紧急救援

时间:2019-03-09 10:37:01      阅读:136      评论:0      收藏:0      [点我收藏+]

这题是一道给我这个菜鸡复习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

 

L2-001 紧急救援

原文:https://www.cnblogs.com/FTA-Macro/p/10499725.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!