NOIP2014 寻找道路 解题报告(dfs+bfs)

在线评测:

http://codevs.cn/problem/3731/

整体思路:

先从(在反向图中)终点dfs一遍,然后所有能到达在dfs中没有搜到的点也标记为不可用,然后正向bfs跑最短路就行,

失误之处:

最开始从起点开始bfs判断哪些点不可用,但是后来发现这样子很多事情在递归里很难处理,于是又想到从每个点都dfs一遍,但是这样子的n2算法太慢了!!!!!所以最后想到从终点开始搜索,

开始我将dfs没有搜到的点全部dfs一遍(反向图),将dfs的点全部标记为不可用,,,然后GG

体会心得:

在面对有起点有终点的情况下,想一下起点和终点有什么区别,换着用有没有什么好处或优势,

写代码前一定仔细想好自己算法的可行性!

AC代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include 
#include 
#include 
#include 
#include 
using  namespace  std;
int  n,m,x,y,s,t,sum,cnt;
int  head[20010],nxt[500000],to[500000],dis[20010];
int  nhead[20010],nnxt[500000],nto[500000],ans;
bool  dvis[20010],fky[20010],vis[20010];
queue < int > dl,js;
void  cr( int  x, int  y)
{
     sum++;
     nxt[sum] = head[x];
     head[x] = sum;
     to[sum] = y;
}
void  ncr( int  x, int  y)
{
     cnt++;
     nnxt[cnt] = nhead[x];
     nhead[x] = cnt;
     nto[cnt] = y;
}
void  dfs( int  x)
{
     for  ( int  tp = nhead[x];tp;tp = nnxt[tp])
     {
         if  (!dvis[nto[tp]]) 
         {
             dvis[nto[tp]] =  true ;
             dfs(nto[tp]);
         }      
     }
}
void  ndfs( int  x)
{
     for  ( int  tp = nhead[x];tp;tp = nnxt[tp])
     {
         if  (!fky[nto[tp]])
         {
             fky[nto[tp]] =  true ;       
         //  ndfs(nto[tp]);
         }
     }
}
void  bfs( int  x)
{
     dl.push(x);
     js.push(0);
     vis[x] =  true ;
     while  (!dl.empty())
     {
         if  (dl.front() == t)
         {
           ans = js.front();
           return ;
         }
         for  ( int  tp = head[dl.front()];tp;tp = nxt[tp])
         {
             if  (!fky[to[tp]] && !vis[to[tp]])
             {      
                 dl.push(to[tp]);
                 js.push(js.front()+1);
                 vis[to[tp]] =  true ;
             }
         }
         dl.pop();
         js.pop();
     }
     
}
int  main()
{
     scanf ( "%d%d" ,&n,&m);
     for  ( int  i = 1;i <= m;i++)
     {
         scanf ( "%d%d" ,&x,&y);
         cr(x,y);
         ncr(y,x);
     }
     scanf ( "%d%d" ,&s,&t);
     dvis[t] =  true ;
     dfs(t);
     for  ( int  i = 1;i <= n;i++)
     {
         if  (!dvis[i]) ndfs(i);
     }
     bfs(s);
     if  (ans || s == t)  printf ( "%d\n" ,ans); else
         printf ( "-1\n" );
     return  0;
}

你可能感兴趣的:(NOIP2014,DFS+BFS)