We can divide the topic into two situations.
In the figure, two red arrows are where two people are now, which is a common situation, since the distance between the two arrows is x.
Let's set the prefix of distance and the ABCD for Si, next time, both should be abbreviated by SA SB SC SD.
That's obvious. D-A > x > C-B < X, that is, D-A > = x + 1, C-B < = X-1
When A= B, C= D, C-B=X, that is, C-B>= X and C-B<=X
Add Super Source Point
It's OK to build edges i n two cases. In the code, n is the super source point, the prefix of I is S (i-1).
#include<iostream> #include<string.h> #include<algorithm> #include<vector> #include<stdio.h> #include<queue> using namespace std; const int MAXN=5e4+5; const int INF=0x7fffffff; struct Point { int v,c; Point(){}; Point(int a,int b){v=a,c=b;} }; vector<Point>v[MAXN]; int dis[MAXN],cnt[MAXN]; bool vis[MAXN]; int n,m,x; void spfa() { memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++){ dis[i]=INF; } vis[n]=1; dis[n]=0; queue<int>q; while(!q.empty())q.pop(); q.push(n); bool f=1; memset(cnt,0,sizeof(cnt)); cnt[n]=1; while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=0;i<v[u].size();i++){ int vv=v[u][i].v; if(dis[vv]>dis[u]+v[u][i].c){ dis[vv]=dis[u]+v[u][i].c; if(!vis[vv]){ vis[vv]=1; q.push(vv); if(++cnt[vv]>n){f=0;break;} } } } if(f==0)break; } if(f==0)cout<<" IMPOSSIBLE"<<endl; else{ for(int i=1;i<n;i++){ //cout<<dis[i]<<endl; cout<<" "<<dis[i]-dis[i-1]; } cout<<endl; } } int main() { int t,cnt=0; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&x); for(int i=0;i<=n;i++){ v[i].clear(); } for(int i=1;i<n;i++){ v[i].push_back(Point(i-1,-1)); v[n].push_back(Point(i,0)); } for(int i=1;i<=m;i++){ int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); a--,b--,c--,d--; if(a==b&&c==d){ v[c].push_back(Point(a,-x)); v[a].push_back(Point(c,x)); } else{ v[d].push_back(Point(a,-(x+1))); v[b].push_back(Point(c,(x-1))); } } cout<<"Case #"<<++cnt<<":"; spfa(); } }