首先不难看出这是最短路
然后一个起点,两个终点。
从起点跑一边dij,比较到两个终点的距离,选小的那个,再以其中一个终点为起点,跑dij,ans加上到另一个终点的距离,就是最终结果。
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; struct node{ int to,nxt,dis; }e[400010]; struct edge{ int val,nm; bool operator < (const edge &x) const { return val > x.val; } }; priority_queue<edge> dij; int head[100001],in[100001],d[100001]; int cnt; int n,m,s1,s2,s3; inline int read(){ int s=0,w=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)w=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){s=s*10+ch-‘0‘;ch=getchar();} return s*w; } inline void add(int from,int to,int dis){ e[++cnt]=(node){to,head[from],dis}; head[from]=cnt; } inline void di(int s){ for(int i=1;i<=n;++i)d[i]=2147483647; memset(in,0,sizeof(in)); dij.push((edge){0,s}); d[s]=0; while(!dij.empty()){ int t=dij.top().nm; dij.pop(); if(in[t])continue; in[t]=1; for(int i=head[t];i!=0;i=e[i].nxt){ if(!in[e[i].to]&&d[t]+e[i].dis<d[e[i].to]){ d[e[i].to]=d[t]+e[i].dis; dij.push((edge){d[e[i].to],e[i].to}); } } } } int main(){ scanf("%d%d%d%d%d",&m,&n,&s1,&s2,&s3); int x,y,z; for(int i=1;i<=m;++i){ scanf("%d%d%d",&x,&y,&z); add(x,y,z);add(y,x,z); } di(s1); int ans=min(d[s2],d[s3]); di(s2); ans+=d[s3]; printf("%d",ans); return 0; }