题解:
以下是三次bfs的AC程序
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; struct Messi { int next,to; long long dis1,dis2; }edge[300001]; int head[100005],num; long long d1[100005],d2[100005],d3[100005]; int vis[100005]; long long ans,ans0,q[4000005],n,m,k,kk[100005],f[100005]; void add(int u,int v,long long dis1,long long dis2) { num++; edge[num].next=head[u]; head[u]=num; edge[num].to=v; edge[num].dis1=dis1; edge[num].dis2=dis2; } void bfs1(int S) {int h,t; memset(vis,0,sizeof(vis)); memset(d1,127/3,sizeof(d1)); h=0;t=1; q[1]=S; d1[S]=0; while (h<t) { h++; h%=4000000; int u=q[h]; vis[u]=0; for (int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if (d1[u]+edge[i].dis1<d1[v]) { d1[v]=d1[u]+edge[i].dis1; if (!vis[v]) { t++; t%=4000000; q[t]=v; vis[v]=1; } } } } } void bfs2(int S) {int h,t,i; memset(vis,0,sizeof(vis)); memset(d2,127/3,sizeof(d2)); h=0;t=1; q[1]=S; d2[S]=0; while (h<t) { h++; h%=4000000; int u=q[h]; vis[u]=0; for (i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if (d2[u]+edge[i].dis2<d2[v]) { d2[v]=d2[u]+edge[i].dis2; if (!vis[v]) { t++; t%=4000000; q[t]=v; vis[v]=1; } } } } } void bfs3(int S) {int h,t,i; memset(vis,0,sizeof(vis)); memset(d3,127/3,sizeof(d3)); h=0;t=1; q[1]=S; d3[S]=0; while (h<t) { h++; h%=4000000; int u=q[h]; vis[u]=0; for (i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if (d3[u]+edge[i].dis1<d3[v]) { d3[v]=d3[u]+edge[i].dis1; if (!vis[v]) { t++; t%=4000000; q[t]=v; vis[v]=1; } } } } } int main() {int S,T,i,u,v; long long dis1,dis2; //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); cin>>n>>m>>k>>S>>T; memset(head,-1,sizeof(head)); for (i=1;i<=k;i++) { scanf("%d",&kk[i]); } for (i=1;i<=m;i++) { scanf("%d%d%lld%lld",&u,&v,&dis1,&dis2); add(u,v,dis1,dis2); add(v,u,dis1,dis2); } bfs1(T); for (i=1;i<=k;i++) ans0+=d1[kk[i]]; bfs2(S); for (i=1;i<=k;i++) { int x=kk[i]; add(0,x,-d1[x],0); } bfs3(0); long long ans=2e15; for (i=1;i<=n;i++) { f[i]=d1[i]+d2[i]+d3[i]; if (f[i]<ans) ans=f[i]; } cout<<ans+ans0; }