P1613 跑路(倍增 + floyd)

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
",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 }
原文地址:https://www.cnblogs.com/mzg1805/p/10405277.html