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 GG where the nodes are trees, and a bird can only fly from a tree TaT_a to TbT_b when (Ta,Tb)(T_a,T_b) is an edge of GG.
Kiara does not know the real graph GG 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 PP explaining how they move. Kiara has spent so much time watching them that she is confident that if a bird can fly directly from aa to bb, then she has witnessed at least one such occurrence. However, it is possible that a bird flew from aa to bb to cc but she only witnessed the stops aa and cc and then added (a,c)(a,c) to PP. It is also possible that a bird flew from aa to bb to cc to dd and she only witnessed aa and dd, and added (a,d)(a,d) to PP , etc. To sum up, she knows that PP contains all the edges of GG and that PP might contain some other edges (a,b)(a,b) for which there is a path from aa to bb in GG (note that PP might not contain all such edges).

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

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

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

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

Limits

1N,M1000001≤N,M≤100000;
0T<N0≤T<N.
Output
Your output should describe the set S(T)S(T). The first line should contain an integer LL, which is the number of nodes in S(T)S(T), followed by LL lines, each containing a different element of S(T)S(T). The elements of 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 11 belongs to S(2)S(2) because the (only) path from 11 to 22 uses (1,2)(1, 2). The node 00 does not belong to S(2)S(2) because the path 0120 \to 1 \to 2 does not use the edge (0,2)(0, 2).

Sample Explanation 2

The graph corresponding to this example is depicted below. For the same reason as in Sample 11, the node 00 does not belong to S(2)S(2) while 1 does. The nodes 33 and 55 do not belong to S(2)S(2) because we do not have edges (3,2)(3, 2) or (5,2)(5, 2). Finally 44 belongs to S(2)S(2) because all paths from 44 to 22 use the edge (4,2)(4, 2).
v1[x]v1[x]中存儲的元素爲v3[y]=truev3[y]=true且能夠到達點xx的點yy
v2[x]v2[x]表示與對於存在邊ex,Te_{x,T}xx是否存在其他路徑可以到達點TT
v3[x]v3[x]表示點xx是否爲存在邊ex,Te_{x,T}點。
將所有有向邊反向建圖,從所有v3[x]=truev3[x]=true的點出發bfsbfs,如果某個某個點xx滿足v3[x]=truev3[x]=true並且v1[x]v1[x]中有不是xx的點,則v2[x]=truev2[x]=true,最終答案爲所有v2v2truetrue的點。
然而如果直接bfsbfs會超時,這裏需要進行一些優化。
對與要從xx訪問到的點yy,如果v1[y]v1[y]中有xx,說明點yy已經被從xx出發訪問過了;如果v1[y].size()>1v1[y].size()>1說明至少有從兩個不同點出發的訪問到該點,即該點所有出入邊都被覆蓋過至少一次這兩種情況都沒必要訪問。

#include<bits/stdc++.h>

#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<int>
#define pii pair<int,int>
#define mii unordered_map<int,int>
#define msi unordered_map<string,int>
#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<<": "<<x<<endl
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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章