https://www.luogu.org/problemnew/show/P1613
思路:
1.读入
2.建图
3.对于每一个点,向距离它 2^k 长度的点连一条长度为 1 的边
4.在新图上跑1~n的最短路
实现
看题解后,发现思路大致正确,但实现有问题;
具体看代码
1 #include <bits/stdc++.h> 2 #define read read() 3 #define up(i,l,r) for(register int i = (l);i <= (r);i++) 4 #define down(i,l,r) for(register int i = (l);i >= (r);i--) 5 #define traversal_vedge(i) for(register int i = head[u]; i ;i = e[i].nxt) 6 #define ll long long 7 using namespace std; 8 int read 9 { 10 int x = 0, f = 1; char ch = getchar(); 11 while(ch < 48 || ch > 57) {if(ch == '-')f = -1; ch = getchar();} 12 while(ch >=48 && ch <=57) {x = 10 * x + ch - 48;ch = getchar();} 13 return x * f; 14 } 15 void write(int x) 16 { 17 if(x < 0) x = -x,putchar('-'); 18 if(x > 9) write(x/10); 19 putchar(x%10 + 48); 20 } 21 //---------------------------------------------------------- 22 const int N = 55; 23 int n,m; 24 int dis[N][N]; 25 bool G[N][N][35]; 26 27 void readdata() 28 { 29 memset(dis,0x3f,sizeof(dis)); 30 n = read; m = read; 31 int u,v; 32 up(i,1,m) 33 { 34 u = read; v = read; 35 dis[u][v] = 1; 36 G[u][v][0] = 1; 37 } 38 } 39 40 void init() 41 { 42 up(p,1,32) 43 up(i,1,n) 44 up(k,1,n) 45 up(j,1,n) 46 { 47 if(G[i][k][p-1] == 1 && G[k][j][p-1] == 1) 48 G[i][j][p] = 1,dis[i][j] = 1;//debug G[i][j][k] -> G[i][j][p] 49 } 50 //预处理 51 } 52 53 void work() 54 { 55 up(k,1,n) up(i,1,n) up(j,1,n) dis[i][j] = min(dis[i][j],dis[i][k] + dis[k][j]); 56 //floyd 57 printf("%d\n",dis[1][n]); 58 } 59 60 int main() 61 { 62 freopen("input.txt","r",stdin); 63 readdata(); 64 init(); 65 work(); 66 return 0; 67 }