这是一题用汗水收获的题。
在纸上用”树-分支“方法画一下发现只有6种走法。
所以求5遍最短路,记录下需要的值,然后比较一下哪种走法最短。
比较6种走法,只能一个个的写,用汗水收获~
【代码】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define INF 1e9;
using namespace std;
int n,m,tot;
struct egde{
int v,d,next;
}e[200100];
int head[1005],vis[1005];
int dis[1005];
void addedge(int u,int v,int d){
e[tot].v=v;
e[tot].next=head[u]; //head[u]记录的是前一个节点的下标
e[tot].d=d;
head[u]=tot++; //记录下标以下次输入用
}
void SPFA(int s){
for(int i=1;i<=n;i++) dis[i]=INF;
mst(vis,0);
queue<int> qu;
qu.push(s);
dis[s]=0;
while(!qu.empty()){
int u=qu.front();
qu.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=e[i].next){ //遍历连接节点u的所有节点
int v=e[i].v;
if(dis[v]>dis[u]+e[i].d){
dis[v]=dis[u]+e[i].d;
if(!vis[v]){
qu.push(v);
vis[v]=1;
}
}
}
}
}
int c[1005][1005];
int main(){
while(~scanf("%d%d",&n,&m)){
mst(head,-1); tot=0;
int s,x1,x2,y1,y2;
scanf("%d%d%d%d%d",&s,&x1,&x2,&y1,&y2);
for(int i=1;i<=m;i++){
int u,v,d;
scanf("%d%d%d",&u,&v,&d);
addedge(u,v,d);
}
SPFA(s);
c[s][x1] = dis[x1]; c[s][y1] = dis[y1];
SPFA(x1);
c[x1][x2] = dis[x2]; c[x1][y1] = dis[y1]; c[x1][y2] = dis[y2];
SPFA(x2);
c[x2][x1] = dis[x1]; c[x2][y1] = dis[y1]; c[x2][y2] = dis[y2];
SPFA(y1);
c[y1][x1] = dis[x1]; c[y1][x2] = dis[x2]; c[y1][y2] = dis[y2];
SPFA(y2);
c[y2][x1] = dis[x1]; c[y2][x2] = dis[x2]; c[y2][y1] = dis[y1];
int ans = c[s][x1] + c[x1][x2] + c[x2][y1] + c[y1][y2];
ans = min(ans , c[s][x1] + c[x1][y1] + c[y1][x2] + c[x2][y2]);
ans = min(ans , c[s][x1] + c[x1][y1] + c[y1][y2] + c[y2][x2]);
ans = min(ans , c[s][y1] + c[y1][x1] + c[x1][x2] + c[x2][y2]);
ans = min(ans , c[s][y1] + c[y1][x1] + c[x1][y2] + c[y2][x2]);
ans = min(ans , c[s][y1] + c[y1][y2] + c[y2][x1] + c[x1][x2]);
printf("%d\n",ans);
}
return 0;
}