【题目链接】
https://www.patest.cn/contests/gplt/L2-001
题目意思
找出最短路中人数和最大的一条,输出对应路径,并求出最短路个数。
解题思路
一题最短路的处理题,在最短路模板上加上人口的数量和路径数的处理。具体看代码更新点的部分。
代码部分
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
#include <math.h>
using namespace std;
const int maxn=505;
const int INF=99999;
int dis[maxn]; ///最短路
int pre[maxn]; ///前驱点
int p[maxn],disp[maxn]; ///人口和最短路时的人口
int n,m,s,d;
int ma[maxn][maxn]; ///地图
void dfs(int d) ///输出路径
{
if (pre[d]!=-1)
{
dfs(pre[d]);
printf(" %d",d);
}
else printf("%d",d);
return;
}
int djs(int s) ///求最短路
{
int vis[maxn];
int j=s,mi,sum;
int way[maxn]; ///路径数
for (int i=0;i<n;i++)
{
dis[i]=ma[s][i];
vis[i]=0;
if (ma[s][i]!=INF) ///如果和起始点通
{
disp[i]=p[i]+p[s];
way[i]=1;
pre[i]=s;
}
}
vis[s]=1;dis[s]=0;
disp[s]=p[s];way[s]=1;
pre[s]=-1;
for (int i=0;i<n-1;i++)
{
mi=INF,sum=INF;
for (int k=0;k<n;k++)
{
if (!vis[k]) ///寻找最近点
{
if (dis[k]<mi)
{
mi=dis[k];
sum=disp[k];
j=k;
}
if (dis[k]==mi&&disp[k]>sum)
{
j=k;
sum=disp[k];
}
}
}
vis[j]=1;
for (int k=0;k<n;k++)
{
if (!vis[k])
{
if (dis[k]==dis[j]+ma[j][k]) ///最短路相等时
{
way[k]+=way[j];
if (disp[k]<p[k]+disp[j])
{
disp[k]=p[k]+disp[j];
pre[k]=j;
}
}
if (dis[k]>dis[j]+ma[j][k])///更短路径时,注:必须要先判断相等,不然更新后注定进入相等情况
{
dis[k]=dis[j]+ma[j][k];
disp[k]=p[k]+disp[j];
way[k]=way[j];
pre[k]=j;
}
}
}
}
return way[d];
}
int main()
{
scanf("%d %d %d %d",&n,&m,&s,&d);
for (int i=0;i<n;i++)
{
for (int j=0;j<n;j++)
ma[i][j]=INF;
dis[i]=INF;
}
for (int i=0;i<n;i++)
scanf("%d",&p[i]);
for (int i=0;i<m;i++)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
if (ma[a][b]>c)
{
ma[a][b]=c;
ma[b][a]=c;
}
}
int t=djs(s);
printf("%d %d\n",t,disp[d]);
dfs(d);
printf("\n");
return 0;
}