Luo Gu P2296 [] to find the way


Ideas: First, if it wants to meet the first condition, we can build the reverse side, from the starting point to go the reverse side, the marker can reach. Has not been labeled point put his father (who point to it) and to mark itself as unreachable, and then seek the shortest, if you encounter marked as unreachable point, to continue, and finally dis [e ] is the answer.

Code:

 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f3f
 3 using namespace std;
 4 int n, m, head[10001], head1[10001], dis[10001], vis[10001], no[10001], mark[10001], num, num1, s, e;
 5 struct node
 6 {
 7     int next, to, val;
 8 }stu[200001], stu1[200001];
 9 inline void add(int x, int Y, int Z) // forward edge 
10  {
 . 11      STU [NUM ++] = .next head [X];
 12 is      STU [NUM] .to = Y;
 13 is      STU [NUM] .val = Z;
 14      head [X] = NUM;
 15      return ;
 16  }
 . 17 inline void ADD1 ( int X, int Y, int Z) // reverse edge 
18 is  {
 . 19      STU1 [num1 ++] = .next head1 [X];
 20 is      STU1 [ num1] .to = Y;
 21 is     STU1 [num1] .val = Z;
 22 is      head1 [X] = num1;
 23 is      return ;
 24  }
 25 inline void dfs ( int U) // point from the end point of the search can reach dfs 
26 is  {
 27      for (Register int I = head1 [U]; I; I = STU1 [I] .next)
 28      {
 29          int K = STU1 [I] .to;
 30          IF ! ( Mark [K])
 31 is          {
 32              Mark [K] = . 1 ;
 33 is              DFS ( K);
 34 is         }
35     }
36     return;
37 }
38 inline void spfa(int s)//求最短路 
39 {
40     queue < int > pru;
41     memset(vis, 0, sizeof(vis));
42     memset(dis, INF, sizeof(dis));
43     dis[s] = 0;
44     vis[s] = 1;
45     pru.push(s);
46     while(!pru.empty())
47      {
 48          int U = pru.front ();
 49          pru.pop ();
 50          VIS [U] = 0 ;
 51 is          for (Register int I = head [U]; I; I = STU [I] .next)
 52 is          {
 53 is              int K = STU [I] .to;
 54 is              IF (NO [K]) // if not down (the condition is not satisfied. 1) 
55              {
 56 is                  Continue ;
 57 is              }
 58              IF (DIS [K]> DIS [ U] + STU [I] .val)
 59              {
 60                 dis[k] = dis[u] + stu[i].val;
61                 if(!vis[k])
62                 {
63                     vis[k] = 1;
64                     pru.push(k);
65                 }
66             }
67         }
68     }
69     return;
70 }
71 signed main()
72 {
73     scanf("%d %d", &n, &m);
74     for(register int i = . 1 , X, Y; I <= m; ++ I)
 75      {
 76          Scanf ( " % D% D " , & X, & Y);
 77          the Add (X, Y, . 1 );
 78          ADD1 (Y, X, . 1 );
 79      }
 80      Scanf ( " % D% D " , & S, & E);
 81      DFS (E);
 82      mark [E] = . 1 ; // remember the end mark search to 
83      for (Register int U = . 1 ; U <= n-; U ++) // search for all points
84      {
 85          IF (! Mark [U]) // not labeled 
86          {
 87              NO [U] = . 1 ; // not go 
88              for (Register int I = head1 [U]; I; STU1 I = [I ] .next) // his father can not go 
89              {
 90                  int K = STU1 [I] .to;
 91 is                  NO [K] = . 1 ;
 92              }
 93          }
 94      }
 95      SPFA (S);
 96      the printf (DIS [ E] == INF? "-1" : "%d", dis[e]);
97     return 0;
98 }

 

Guess you like

Origin www.cnblogs.com/qqq1112/p/11536145.html