用单源最短路径(dijkstra)求出最短路径,顺带求数量和最大值。我用了两种方法:矩阵和邻接表法。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <stack>
#include <math.h>
#include <queue>
#include <limits.h>
#include <algorithm>
#include <sstream>
using namespace std;
// 矩阵法
const int mx=5e2+10;
bool vis[mx];
int dis[mx],mp[mx][mx],v[mx],team[mx],pcnt[mx];
int n,m,s,e,c1,c2,l;
int main()
{
//freopen("input.txt","r",stdin);
cin>>n>>m>>s>>e;
for(int i=0;i<n;i++) cin>>v[i];
memset(mp,-1,sizeof(mp));
memset(dis,-1,sizeof(dis));
while(m--)
{
cin>>c1>>c2>>l;
mp[c1][c2]=mp[c2][c1]=l;
}
team[s]=v[s],pcnt[s]=1,dis[s]=0;
while(true)
{
int now=-1;
for(int i=0;i<n;i++) //找距离最近且未被访问的点
{
if(!vis[i] && dis[i]!=-1)
{
if(now==-1) now=i;
else now=dis[now]<dis[i]?now:i;
}
}
if(now==-1) break;
vis[now]=true;
for(int j=0;j<n;j++)
{
if(mp[now][j]!=-1)
{
if(dis[j]==-1 || dis[j]>dis[now]+mp[now][j])
{
dis[j]=mp[now][j]+dis[now];
team[j]=team[now]+v[j];
pcnt[j]=pcnt[now];
}
else if(dis[j]==dis[now]+mp[now][j])
pcnt[j]+=pcnt[now],team[j]=max(team[j],team[now]+v[j]);
}
}
}
cout<<pcnt[e]<<" "<<team[e]<<endl;
return 0;
}
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <stack>
#include <math.h>
#include <queue>
#include <limits.h>
#include <algorithm>
#include <sstream>
using namespace std;
// 邻接链表法
const int mx=5e2+10;
bool vis[mx];
int dis[mx],team[mx],v[mx],pcnt[mx];
int n,m,s,e,c1,c2,l;
struct E{
int nt,len;
};
vector<E> edge[mx];
E tmp;
int main()
{
//freopen("input.txt","r",stdin);
cin>>n>>m>>s>>e;
memset(dis,-1,sizeof(dis));
for(int i=0;i<n;i++) cin>>v[i];
while(m--)
{
cin>>c1>>c2>>l;
tmp.len=l;
tmp.nt=c2;
edge[c1].push_back(tmp);
tmp.nt=c1;
edge[c2].push_back(tmp);
}
dis[s]=0,pcnt[s]=1,team[s]=v[s],vis[s]=true;
int now=s;
for(int i=0;i<n;i++)//循环n-1次
{
for(int j=0;j<edge[now].size();j++)
{
int t=edge[now][j].nt;
int c=edge[now][j].len;
if(vis[t]) continue;
if(dis[t]==-1 || dis[t]>dis[now]+c)
dis[t]=dis[now]+c,team[t]=team[now]+v[t],pcnt[t]=pcnt[now];
else if(dis[t]==dis[now]+c)
team[t]=max(team[t],team[now]+v[t]),pcnt[t]+=pcnt[now];
}
int mi=INT_MAX;
for(int j=0;j<n;j++)
{
if(vis[j] || dis[j]==-1) continue;
if(dis[j]<mi)
{
mi=dis[j];
now=j;
}
}
vis[now]=true;
}
cout<<pcnt[e]<<" "<<team[e]<<endl;
return 0;
}