The question description is as follows.
Idea: starting from a certain point can be infinite times, which is like a stream problem. You can use a stream at the beginning.
The problem is abstracted in this way (the problem is simply abstracted, and the key is how to transform and abstract): This shortest time is actually a process where all vertices start from the starting point and pass through a path (at least ), in the process of gathering points, the shortest time must be the longest path (the longest time). If you do not need to take over all points, the shortest path is used, so you need to take over all points, it must be Max (start point to I, I to end point) (traverse I ).
#include<iostream>#include<cstring>#include<cstdio>#include<queue>using namespace std;const int inf=0x3f3f3f3f;const int maxn=1001, maxe=200010;int head[maxn]; int nume=0;int e[maxe][3];void inline adde(int i,int j,int w){ e[nume][0]=j;e[nume][1]=head[i];head[i]=nume; e[nume++][2]=w; e[nume][0]=i;e[nume][1]=head[j];head[j]=nume; e[nume++][2]=w;}int ds[maxn];int dt[maxn]; int n,m;void spfa(int s,int d[]){ int inq[maxn]; memset(inq,0,sizeof(inq)); d[s]=0; queue<int>q; q.push(s); while(!q.empty()) { int cur=q.front(); q.pop(); inq[cur]=0; for(int j=head[cur];j!=-1;j=e[j][1]) { int v=e[j][0]; if(d[v]>d[cur]+e[j][2]) { d[v]=d[cur]+e[j][2]; if(!inq[v]) { inq[v]=1; q.push(v); } } } }}int solve(){ int minmax=0; for(int i=0;i<n;i++) { if(ds[i]+dt[i]>minmax) minmax=ds[i]+dt[i]; } return minmax;}void init(){ nume=0; for(int i=0;i<n;i++) { head[i]=-1; ds[i]=inf; dt[i]=inf; }}int main(){ int T; scanf("%d",&T);int ct=1; while(T--) { scanf("%d%d",&n,&m); init(); int aa,bb,cc; for(int i=0;i<m;i++) { scanf("%d%d%d",&aa,&bb,&cc); adde(aa,bb,cc); } int s,t; scanf("%d%d",&s,&t); spfa(s,ds); spfa(t,dt); int ans=solve(); printf("Case #%d: %d\n",ct++,ans); } return 0;}
Acdream1198 ask a lot of people to start from a certain point and converge on a certain point to traverse the shortest time of all points at least once.