we find that the remainder of the shutterings P is the same every time it is added, and it's easy to think about P-chunking
When P>sqrt (n), a maximum of O (sqrt (n)) edges are connected, directly connecting the edges
When P<=sqrt (n),
Divide the graph into sqrt (n) +1 layers, the bottom of which represents the original node
P=1, 2, 3 ... from bottom to top. When the node
For each p, the points with the same remainder of modulo p are connected sequentially
For each read-in P, a 0-weighted edge is attached from the bottom to the corresponding P-layer node
Is it said that SPFA fast?
It's kind of a good question.
O (3*N*SQRT (n) +2*num*sqrt (n) + (M-num))
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <iostream > #include <algorithm> #define MAXN 30010#define N 15000010#define inf 1000000000using namespace Std;int head[110 *maxn],to[n],len[n],next[n],dis[110*maxn];bool Vis[110*maxn];int Pos[110][maxn],q[110*maxn];int n,m,num,block,cnt , s,t;void addedge (int x,int y,int z) {num++;to[num]=y;len[num]=z;next[num]=head[x];head[x]=num;} void Spfa () {for (int i=0;i<=cnt;i++) Dis[i]=inf;int l=0,r=1;q[1]=s;vis[s]=1;dis[s]=0;while (l!=r) {l++;if (l==110* MAXN) l=0;int x=q[l];for (int p=head[x];p; p=next[p]) if (Dis[x]+len[p]<dis[to[p]]) {dis[to[p]]=dis[x]+len[p]; if (!vis[to[p]]) {r++;if (R==110*MAXN) r=0; VIS[TO[P]]=1;Q[R]=TO[P]; }}vis[x]=0;}} int main () {scanf ("%d%d", &n,&m), cnt=n-1;block=min ((int) sqrt (n), +), for (Int. i=1;i<=block;i++) for (int j= 0;j<i;j++) for (int k=j;k<n;k+=i) {pos[i][k]=++cnt; Addedge (cnt,k,0); if (k>=i) Addedge (cnt-1,cnt,1), Addedge (cnt,cnt-1,1); }for (int i=1;i<=m;i++) {int b,p;scanf ("%d%d", &b,&p), if (i==1) s=b;if (i==2) t=b;if (p<=block) Addedge (B, pos[p][b],0); else{for (int j=1; b+j*p<n;j++) Addedge (B,B+J*P,J); for (int j=1; b-j*p>=0;j++) Addedge (B,B-J*P,J);}} SPFA (); if (dis[t]!=inf) printf ("%d\n", dis[t]); else printf (" -1\n"); return 0;}
"bzoj4070" [Apio2015] Jakarta skyscraper sub-block + shortest circuit