枚举,最短路。
求出5个点出发的最短路,然后枚举一下这些点之间走的顺序。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-8; void File() { freopen("D:\in.txt","r",stdin); freopen("D:\out.txt","w",stdout); } template <class T> inline void read(T &x) { char c = getchar(); x = 0;while(!isdigit(c)) c = getchar(); while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } } const int INF=0x7FFFFFFF; const int maxn=1010; int n,m,sz; struct Edge {int u,v,w,nx; }e[200010]; int h[maxn]; int s,p1,q1,p2,q2; int dis[maxn][maxn]; bool flag[maxn]; void add(int a,int b,int c) { e[sz].u=a; e[sz].v=b; e[sz].w=c; e[sz].nx=h[a]; h[a]=sz++; } void spfa(int st) { for(int i=0;i<=n;i++) dis[st][i]=INF; queue<int>Q; memset(flag,0,sizeof flag); flag[st]=1; Q.push(st); dis[st][st]=0; while(!Q.empty()) { int f=Q.front(); Q.pop(); flag[f]=0; for(int i=h[f];i!=-1;i=e[i].nx) { if(dis[st][f]+e[i].w<dis[st][e[i].v]) { dis[st][e[i].v]=dis[st][f]+e[i].w; if(flag[e[i].v]==0) { flag[e[i].v]=1; Q.push(e[i].v); } } } } } int main() { while(~scanf("%d%d",&n,&m)) { scanf("%d%d%d%d%d",&s,&p1,&q1,&p2,&q2); memset(h,-1,sizeof h); sz=0; for(int i=1;i<=m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); } spfa(s); spfa(p1); spfa(p2); spfa(q1); spfa(q2); LL Ans[10]; Ans[0]=(LL)dis[s][p1]+(LL)dis[p1][q1]+(LL)dis[q1][p2]+(LL)dis[p2][q2]; Ans[1]=(LL)dis[s][p1]+(LL)dis[p1][p2]+(LL)dis[p2][q1]+(LL)dis[q1][q2]; Ans[2]=(LL)dis[s][p1]+(LL)dis[p1][p2]+(LL)dis[p2][q2]+(LL)dis[q2][q1]; Ans[3]=(LL)dis[s][p2]+(LL)dis[p2][q2]+(LL)dis[q2][p1]+(LL)dis[p1][q1]; Ans[4]=(LL)dis[s][p2]+(LL)dis[p2][p1]+(LL)dis[p1][q1]+(LL)dis[q1][q2]; Ans[5]=(LL)dis[s][p2]+(LL)dis[p2][p1]+(LL)dis[p1][q2]+(LL)dis[q2][q1]; LL ans=Ans[0]; for(int i=1;i<6;i++) ans=min(ans,Ans[i]); printf("%lld ",ans); } return 0; }