Birdwatching

Kiara studies an odd species of birds that travel in a very peculiar way. Their movements are best explained using the language of graphs: there exists a directed graph G G G where the nodes are trees, and a bird can only fly from a tree T a T_a Ta to T b T_b Tb when ( T a , T b ) (T_a,T_b) (Ta,Tb) is an edge of G G G.
Kiara does not know the real graph G G G governing the flight of these birds but, in her previous field study, Kiara has collected data from the journey of many birds. Using this, she has devised a graph P P P explaining how they move. Kiara has spent so much time watching them that she is confident that if a bird can fly directly from a a a to b b b, then she has witnessed at least one such occurrence. However, it is possible that a bird flew from a a a to b b b to c c c but she only witnessed the stops a a a and c c c and then added ( a , c ) (a,c) (a,c) to P P P. It is also possible that a bird flew from a a a to b b b to c c c to d d d and she only witnessed a a a and d d d, and added ( a , d ) (a,d) (a,d) to P P P , etc. To sum up, she knows that P P P contains all the edges of G G G and that P P P might contain some other edges ( a , b ) (a,b) (a,b) for which there is a path from a a a to b b b in G G G (note that P P P might not contain all such edges).

For her next field study, Kiara has decided to install her base next to a given tree T T T. To be warned of the arrival of birds on T T T, she would also like to install detectors on the trees where the birds can come from (i.e. the trees T ′ T^′ T such that there is an edge ( T ′ , T ) ( T^′,T) (T,T) in G G G ). As detectors are not cheap, she only wants to install detectors on the trees T ′ T^′ T for which she is sure that ( T ′ , T ) (T^′,T) (T,T) belongs to G G G.

Kiara is sure that an edge ( a , b ) (a,b) (a,b) belongs to G G G when ( a , b ) (a,b) (a,b) is an edge of P P P and all the paths in P P P starting from a a a and ending in b b b use the edge ( a , b ) (a,b) (a,b). Kiara asks you to compute the set S ( T ) S(T) S(T) of trees T ′ T^′ T for which she is sure that ( T ′ , T ) (T^′,T) (T,T) is an edge of G G G.

Input
The input describes the graph P P P. The first line contains three space-separated integers N N N, M M M, and T T T: N N N is the number of nodes of P P P, M M M is the number of edges of P P P and T T T is the node corresponding to the tree on which Kiara will install her base.

The next M M M lines describe the edges of the graph P P P. Each contains two space-separated integers a a a and b b b ( 0 ≤ a , b < N a n d   a ≠ b ) (0≤a, b(0a,b<Nand a=b) stating that ( a , b ) ∈ P (a,b) \in P (a,b)P . It is guaranteed that the same pair ( a , b ) (a,b) (a,b) will not appear twice.

Limits

1 ≤ N , M ≤ 100000 1≤N,M≤100000 1N,M100000;
0 ≤ T < N 0≤T0T<N.
Output
Your output should describe the set S ( T ) S(T) S(T). The first line should contain an integer L L L, which is the number of nodes in S ( T ) S(T) S(T), followed by L L L lines, each containing a different element of S ( T ) S(T) S(T). The elements of S ( T ) S(T) S(T) should be printed in increasing order, with one element per line.

Examples

input
3 3 2
0 1
0 2
1 2
output
1
1
input
6 8 2
0 1
0 2
1 2
2 0
2 3
3 4
4 2
2 5
output
2
1
4

Note
Sample Explanation 1

The graph corresponding to this example is depicted below. The node 1 1 1 belongs to S ( 2 ) S(2) S(2) because the (only) path from 1 1 1 to 2 2 2 uses ( 1 , 2 ) (1, 2) (1,2). The node 0 0 0 does not belong to S ( 2 ) S(2) S(2) because the path 0 → 1 → 2 0 \to 1 \to 2 012 does not use the edge ( 0 , 2 ) (0, 2) (0,2).

Sample Explanation 2

The graph corresponding to this example is depicted below. For the same reason as in Sample 1 1 1, the node 0 0 0 does not belong to S ( 2 ) S(2) S(2) while 1 does. The nodes 3 3 3 and 5 5 5 do not belong to S ( 2 ) S(2) S(2) because we do not have edges ( 3 , 2 ) (3, 2) (3,2) or ( 5 , 2 ) (5, 2) (5,2). Finally 4 4 4 belongs to S ( 2 ) S(2) S(2) because all paths from 4 4 4 to 2 2 2 use the edge ( 4 , 2 ) (4, 2) (4,2).
v 1 [ x ] v1[x] v1[x]中存储的元素为 v 3 [ y ] = t r u e v3[y]=true v3[y]=true且能够到达点 x x x的点 y y y
v 2 [ x ] v2[x] v2[x]表示与对于存在边 e x , T e_{x,T} ex,T x x x是否存在其他路径可以到达点 T T T
v 3 [ x ] v3[x] v3[x]表示点 x x x是否为存在边 e x , T e_{x,T} ex,T点。
将所有有向边反向建图,从所有 v 3 [ x ] = t r u e v3[x]=true v3[x]=true的点出发 b f s bfs bfs,如果某个某个点 x x x满足 v 3 [ x ] = t r u e v3[x]=true v3[x]=true并且 v 1 [ x ] v1[x] v1[x]中有不是 x x x的点,则 v 2 [ x ] = t r u e v2[x]=true v2[x]=true,最终答案为所有 v 2 v2 v2 t r u e true true的点。
然而如果直接 b f s bfs bfs会超时,这里需要进行一些优化。
对与要从 x x x访问到的点 y y y,如果 v 1 [ y ] v1[y] v1[y]中有 x x x,说明点 y y y已经被从 x x x出发访问过了;如果 v 1 [ y ] . s i z e ( ) > 1 v1[y].size()>1 v1[y].size()>1说明至少有从两个不同点出发的访问到该点,即该点所有出入边都被覆盖过至少一次这两种情况都没必要访问。

#include

#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define sc(a) scahf("%c",&a);
#define ss(a) scanf("%s",a)
#define pi(a) printf("%d\n",a)
#define pl(a) printf("%lld\n",a)
#define pc(a) putchar(a)
#define ms(a) memset(a,0,sizeof(a))
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define repd(i, a, b) for(register int i=a;i>=b;--i)
#define reps(s) for(register int i=head[s];i;i=Next[i])
#define ll long long
#define ull unsigned long long
#define vi vector
#define pii pair
#define mii unordered_map
#define msi unordered_map
#define lowbit(x) ((x)&(-(x)))
#define ce(i, r) i==r?'\n':' '
#define pb push_back
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define pr(x) cout<<#x<<": "<
using namespace std;

inline int qr() {
    int f = 0, fu = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-')fu = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        f = (f << 3) + (f << 1) + c - 48;
        c = getchar();
    }
    return f * fu;
}

const int N = 1e5 + 10;
int head[N], ver[N << 1], Next[N << 1], tot;
int n, m, st;
vi p;
bool v2[N], v3[N];
unordered_set<int> v1[N];

inline void add(int x, int y) {
    ver[++tot] = y;
    Next[tot] = head[x];
    head[x] = tot;
}

inline void read() {
    n = qr(), m = qr(), st = qr();
    while (m--) {
        int x = qr(), y = qr();
        add(y, x);
    }
}

inline void bfs() {
    queue<pii > q;
    for (auto it:p)q.push({it, it});
    while (!q.empty()) {
        pii x = q.front();
        q.pop();
        reps(x.fi) {
            int y = ver[i];
            if (v1[y].size() >= 2 || v1[y].count(x.se))continue;
            if (v3[y] && x.se != y)v2[y] = true;
            v1[y].insert(x.se), q.push({y, x.se});
        }
    }
}

int main() {
    read();
    reps(st) {
        int y = ver[i];
        p.pb(y), v3[y] = true, v1[y].insert(y), v1[st].insert(y);
    }
    bfs();
    vi ans;
    for (auto it:p)if (!v2[it])ans.pb(it);
    pi(ans.size());
    sort(ans.begin(), ans.end());
    for (auto it:ans)pi(it);
    return 0;
}

你可能感兴趣的:(bfs,ACM)