题目
分析
dijkstra,打印路径,详细见代码。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=550;
const ll mod=998244353;
const ll INF=0x3f3f3f3f;
const double pi=acos(-1);
int val[maxn],mp[maxn][maxn];
int path[maxn],dis[maxn];
int n,m,s,d;
int vis[maxn],maxval[maxn],pre[maxn];
void init() //初始化
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(i!=j) mp[i][j]=mp[j][i]=INF;
else mp[i][j]=mp[j][i]=0;
}
}
memset(vis,0,sizeof(vis));
memset(maxval,0,sizeof(maxval));
memset(path,0,sizeof(path));
memset(pre,-1,sizeof(pre));
}
void dijkstra()
{
for(int i=0;i<n;i++) //初始化与起点距离
{
dis[i]=mp[s][i];
}
maxval[s]=val[s]; //初始化起点相关值
path[s]=1;
while(1) //循环寻找最短路
{
int minn=INF,p=-1;
for(int i=0;i<n;i++) //找当前最短路径,存点
{
if(dis[i]<minn&&vis[i]==0)
{
minn=dis[i];
p=i;
}
}
if(p==-1) break; //找不到结束循环
vis[p]=1;
for(int i=0;i<n;i++) //更新相关值
{
if(vis[i]==0)
{
if(dis[p]+mp[p][i]<dis[i]) //加入此点,路径变短
{
dis[i]=dis[p]+mp[p][i];
pre[i]=p; //记录路径
maxval[i]=maxval[p]+val[i];
path[i]=path[p]; //记录路径条数
}
else if(dis[p]+mp[p][i]==dis[i]) //判断长度相等时,救援队数是否更优
{
path[i]+=path[p]; //增加路径条数
if(maxval[p]+val[i]>maxval[i])
{
maxval[i]=maxval[p]+val[i];
pre[i]=p;
}
}
}
}
}
}
void preprint(int e) //倒序打印路径
{
if(pre[e]!=-1)
{
preprint(pre[e]);
cout<<pre[e]<<" ";
}
}
int main()
{
cin>>n>>m>>s>>d;
for(int i=0;i<n;i++)
{
cin>>val[i];
}
init();
for(int i=0;i<m;i++)
{
int x,y,v;
cin>>x>>y>>v;
mp[x][y]=mp[y][x]=min(mp[x][y],v);
}
dijkstra();
cout<<path[d]<<" "<<maxval[d]<<endl;
preprint(d);
cout<<d<<endl;
return 0;
}