K. Birdwatching 题解(bfs)

原题链接https://codeforces.ml/gym/294361/problem/K

题意

有一个原图G和给你一个图P,都是有向图,G是P的子集

G与P的关系是:G图中可能没有a到b这条边,但是有路径可以到从a到b,那么P图可能就会多一条a到b的边。

现在给你P图和节点T,试问边(a->T)中哪些a是一定存在于原图G的

 

 

解法

可以想象的是对于所有a,如果有两条路径不重复路径能到T那就是不一定存在于原图。

为了方便可以把图反着建立,从T点开始bfs,找所有相邻点是否有两条以上路径到达,注意要排除a是一个环中唯一与T相邻的点的情况(这种时候也是一定存在于原图的)。

写法很多种,主要按方法走就行了

 

CODE:

 1 /*
 2 https://codeforces.ml/gym/294361/problem/K
 3 bfs graph
 4 */
 5 #include<bits/stdc++.h>
 6 #define to_l(a) ((a)<<1)
 7 #define to_r(a) ((a)<<1|1)
 8 #define lowbit(a) ((a)&(-a))
 9 using namespace std;
10 typedef long long int ll;
11 typedef unsigned long long int ull;
12 const int int_inf=0x3f3f3f3f;
13 const ll ll_inf=0x3f3f3f3f3f3f3f3f;
14 const int max_n=1e5+5;
15 int head[max_n],to[max_n],nxt[max_n],ind;
16 inline void add(int a,int b){
17     to[++ind]=b;
18     nxt[ind]=head[a];
19     head[a]=ind;
20     return ;
21 }
22 int vis[max_n],from[max_n];
23 void bfs(int s)
24 {
25     queue<int> q;
26     queue<int> qq;
27     while(!q.empty()) q.pop();
28     while(!qq.empty()) qq.pop();
29     for(int i=head[s];i;i=nxt[i]){
30         q.push(to[i]);
31         qq.push(to[i]);
32         from[to[i]]=to[i];
33         vis[to[i]]=1;
34     }
35     vis[s]=2;
36     while(!q.empty()){
37         int t=q.front(),tt=qq.front();
38         q.pop(),qq.pop();
39         for(int i=head[t];i;i=nxt[i]){
40             if(vis[to[i]]!=2){
41                 if(vis[to[i]]){
42                     if(tt!=from[to[i]]){
43                         vis[to[i]]++;
44                         q.push(to[i]);
45                         qq.push(tt);
46                     }
47                 }else{
48                     vis[to[i]]++;
49                     from[to[i]]=tt;
50                     q.push(to[i]);
51                     qq.push(tt);
52                 }
53             }
54         }
55     }
56     return ;
57 }
58 int main()
59 {
60     ios::sync_with_stdio(false);
61     cin.tie(0);
62     int i,j;
63     int n,m,t;
64     cin>>n>>m>>t;
65     ind=0;
66     for(i=0;i<n;i++) from[i]=-1;
67     for(i=0;i<m;i++){
68         int a,b;
69         cin>>a>>b;
70         add(b,a);
71     }
72     bfs(t);
73     vector<int>ans;
74     ans.clear();
75     for(i=head[t];i;i=nxt[i]){
76         if(vis[to[i]]!=2){
77             vis[to[i]]=3;
78         }
79     }
80     for(i=0;i<n;i++){
81         if(vis[i]==3){
82             ans.push_back(i);
83         }
84     }
85     cout<<ans.size()<<endl;
86     for(i=0;i<ans.size();i++){
87         cout<<ans[i]<<endl;
88     }
89     return 0;
90 }

 

posted @ 2020-09-12 20:28  Alpaca00  阅读(229)  评论(0)    收藏  举报