P2296 寻找道路

链接:Miku

--------------------------------------------

一道很好的bfs,dfs混合练手题

--------------------------------------------

这一道题看第一眼:愚蠢的bfs求最短路,有什么难的!

然后看见了一堆附加条件:

1 路径上的所有点的出边所指向的点都直接或间接与终点连通。
2 在满足条件11的情况下使路径最短
Ac

等等,与终点联通?难道我们要把每一个点dfs能不能行吗?

然而你想一想,如果你能从这个点走到终点,那么倒着走不久走回来了?

(然而这是有向图额)

那么就建反图,dfs所有的能到终点的点

void dfs(int now){
    if(vis[now])
    return ;
    vis[now]=1;
    for(int i=h2[now];i;i=e2[i].ne){
        dfs(e2[i].to);
    }
}
dfs

-------------------------------------------

预处理结束,重新看一下条件1,好吧,还有一步

预处理
for(int i=1;i<=n;++i){
        int f=1;
        for(int j=h1[i];j;j=e1[j].ne){
            if(!vis[e1[j].to]){
                f=0;
                break;
            }
        }
        if(!f){
            vis2[i]=1;
        }
    }

---------------------------------------------

处理完这些后,就是个简单的bfs了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 using namespace std;
 5 int vis[10001];
 6 int p;
 7 int p2;
 8 struct b{
 9     int to;
10     int ne;
11 }e1[200001],e2[200001];
12 struct bb{
13     int p;
14     int t;
15 } ;
16 queue <bb> q;
17 int vis2[10001];
18 int n,m;
19 int x,y;
20 int dis[10001];
21 int h1[10001],h2[10001];
22 int s,t;
23 void add(int f,int t){
24     p++;
25     e1[p].to=t;
26     e1[p].ne=h1[f];
27     h1[f]=p;
28 }
29 void add2(int f,int t){
30     p2++;
31     e2[p2].to=t;
32     e2[p2].ne=h2[f];
33     h2[f]=p2;
34 }
35 void dfs(int now){
36     if(vis[now])
37     return ;
38     vis[now]=1;
39     for(int i=h2[now];i;i=e2[i].ne){
40         dfs(e2[i].to);
41     }
42 }
43 void bfs(int st){
44     bb now;
45     now.p=st;
46     now.t=0;
47     q.push(now);
48     while(!q.empty()){
49         now=q.front();
50         q.pop();
51         vis2[now.p]=1;
52         if(now.p==t){
53             cout<<now.t;
54             return ;
55         }
56         for(int i=h1[now.p];i;i=e1[i].ne){
57             int v=e1[i].to;
58             if(vis[v]&&!vis2[v]){
59                 bb nn;
60                 nn.p=v;
61                 nn.t=now.t+1;
62                 q.push(nn);
63             }
64         }
65     }
66     cout<<-1;
67 }
68 int main(){
69     scanf("%d%d",&n,&m);
70     for(int i=1;i<=m;++i){
71         scanf("%d%d",&x,&y);
72         add(x,y);
73         add2(y,x);
74     }
75     scanf("%d%d",&s,&t);
76     dfs(t);
77     for(int i=1;i<=n;++i){
78         int f=1;
79         for(int j=h1[i];j;j=e1[j].ne){
80             if(!vis[e1[j].to]){
81                 f=0;
82                 break;
83             }
84         }
85         if(!f){
86             vis2[i]=1;
87         }
88     }
89     bfs(s);    
90     return 0;
91 }
ac
posted @ 2020-01-17 08:39  Simex  阅读(110)  评论(0编辑  收藏  举报