It's probably called multiplication Floyd?
Obviously up to 200 points ... f[i][j][k] represents the smallest distance from J to K, taking the 2^i step. It's just a random shift.
The query is to get up the n bits that are 1.
1#include <cstdio>2#include <iostream>3#include <cstring>4#include <algorithm>5#include <cstdlib>6 #definell Long Long7 #defineull unsigned long Long8 #defineD Double9 using namespacestd;Ten Const intmaxn=1023, inf=1002333333; One structmat{intf[202][202];} F,c; A intid[1023]; - inti,j,k,n,m,cnt,st,ed; - the intRA,FH;CharRx; -InlineintRead () { -Rx=getchar (), ra=0, fh=1; - while((rx<'0'|| Rx>'9') &&rx!='-') rx=GetChar (); + if(rx=='-') fh=-1, rx=GetChar (); - while(rx>='0'&&rx<='9') ra*=Ten, ra+=rx- -, Rx=getchar ();returnra*fh; + } AInlineintMinintAintb) {returnA<b?a:b;} atInline Mat Run (Mat &a,mat &b) { -Registerinti,j,k; - for(i=1; i<=cnt;i++) for(j=1; j<=cnt;j++) - for(c.f[i][j]=inf,k=1; k<=cnt;k++) -C.f[i][j]=min (c.f[i][j],a.f[i][k]+b.f[k][j]); - returnC; in } - intMain () { toN=read (), M=read (), St=read (), Ed=read ();intx; +memset (F.F, -,sizeof(F.F)); - for(i=1; i<=m;i++){ theX=read (), J=read (), k=read (); * if(!id[j]) id[j]=++cnt;if(!id[k]) id[k]=++CNT; $j=id[j],k=Id[k];Panax NotoginsengF.f[j][k]=min (f.f[j][k],x), f.f[k][j]=min (f.f[k][j],x); - } theMat g=f;n--; + while(n) { A if(n&1) g=run (g,f); then>>=1; + if(n) f=run (f,f); - } $printf"%d\n", g.f[id[st]][id[ed]]); $}
View Code
[bzoj1706] [usaco2007 nov]relays Cow relay Run