跑dij的时候同时维护三个变量(pre路径上该点的前一点,cnt最短路数目,sum救援人数)。
25分
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int n,m,s,d;
int mp[510][510];
int a[510];
int f[510],dis[510],pre[510],cnt[510],sum[510];
void print(int e)
{
if(e==s)
{
cout<<s;
return;
}
print(pre[e]);
cout<<" "<<e;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>m>>s>>d;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
mp[i][j]=inf;
}
}
while(m--)
{
int a,b,c;cin>>a>>b>>c;
mp[a][b]=mp[b][a]=c;
}
fill(dis,dis+510,inf);
dis[s]=0;sum[s]=a[s];cnt[s]=1;
for(int i=0;i<n;i++)
{
int ff=-1,minn=inf;
for(int j=0;j<n;j++)
{
if(!f[j]&&dis[j]<minn)
{
ff=j;
minn=dis[j];
}
}
if(ff==-1)break;
f[ff]=1;
for(int j=0;j<n;j++)
{
if(!f[j]&&dis[j]>dis[ff]+mp[ff][j])
{
sum[j]=sum[ff]+a[j];
dis[j]=dis[ff]+mp[ff][j];
pre[j]=ff;
cnt[j]=cnt[ff];
}
else if(!f[j]&&dis[j]==dis[ff]+mp[ff][j])
{
cnt[j]+=cnt[ff];
if(sum[j]<sum[ff]+a[j])
{
sum[j]=sum[ff]+a[j];
pre[j]=ff;
}
}
}
}
cout<<cnt[d]<<" "<<sum[d]<<"\n";
print(d);
return 0;
}
dfs21分,最后一个样例会tle
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct edge
{
int v,to,nxt;
}e[250010];
int idx=0;
int head[510];
void add(int a,int b,int c)
{
e[idx].to=b;
e[idx].v=c;
e[idx].nxt=head[a];
head[a]=idx++;
}
int n,m,s,d;
int a[510];
int minn=1e9,k=0,maxn=0;
int f[510];
int a1[510],a2[510];
int cnt1=0,cnt2=0;
void dfs(int x,int ans,int sum,int cnt)
{
if(x==d)
{
if(ans==minn)
{
k++;
if(sum>maxn)
{
maxn=sum;
cnt2=cnt;
for(int i=0;i<cnt;i++)a2[i]=a1[i];
}
}
else if(ans<minn)
{
minn=ans;
k=1;
maxn=sum;
cnt2=cnt;
for(int i=0;i<cnt;i++)a2[i]=a1[i];
}
return ;
}
for(int i=head[x];i!=-1;i=e[i].nxt)
{
if(!f[e[i].to])
{
f[e[i].to]=1;
a1[cnt++]=e[i].to;
dfs(e[i].to,ans+e[i].v,sum+a[e[i].to],cnt);
f[e[i].to]=0;
cnt--;
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
memset(head,-1,sizeof head);
cin>>n>>m>>s>>d;
for(int i=0;i<n;i++)cin>>a[i];
while(m--)
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
}
a1[cnt1++]=s;
f[s]=1;
dfs(s,0,a[s],cnt1);
//cout<<k<<" "<<minn<<"\n";
cout<<k<<" "<<maxn<<"\n";
cout<<a2[0];
for(int i=1;i<cnt2;i++)cout<<" "<<a2[i];
cout<<"\n";
return 0;
}