洛谷:https://www.luogu.com.cn/problem/P3110
由题意我们可知,需要找出两只牛的汇合点,再求出此点到终点的最短路。
之后再将问题转化,分别以1、2、n点为源点,求三次SPFA,再将dis累加,最小值即为答案。
代码如下:
#include<stdio.h> #include<queue> #include<cstring> using namespace std; #define MAX 80001 int head[MAX],to[MAX],nxt[MAX]; int dis[MAX]; int ans[MAX]; bool inQ[MAX]; queue<int>q; int tot=0; int min(int x,int y) { return x<y?x:y; } void spfa(int s,int v) { memset(dis,0x3f3f,sizeof(dis)); dis[s]=0; q.push(s); inQ[s]=1; while(!q.empty()) { int p=q.front(); q.pop(); inQ[p]=0; for(int i=head[p];i;i=nxt[i]) { int y=to[i]; if(dis[y]>dis[p]+v) { dis[y]=dis[p]+v; if(inQ[y]==0) q.push(y),inQ[y]=1; } } } } void add(int x,int y) { to[++tot]=y; nxt[tot]=head[x]; head[x]=tot; } int main() { int b,e,p,n,m; scanf("%d%d%d%d%d",&b,&e,&p,&n,&m); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } spfa(1,b); for(int i=1;i<=n;i++) ans[i]+=dis[i]; spfa(2,e); for(int i=1;i<=n;i++) ans[i]+=dis[i]; spfa(n,p); int a=0x3f3f3f3f; for(int i=1;i<=n;i++) { ans[i]+=dis[i]; a=min(ans[i],a); } printf("%d",a); }