【组队排位赛#5】K - Birdwatching BFS

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 where the nodes are trees, and a bird can only fly from a tree Ta to Tb when (Ta,Tb) is an edge of G.
Kiara does not know the real graph 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 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 to b, then she has witnessed at least one such occurrence. However, it is possible that a bird flew from a to b to c but she only witnessed the stops a and c and then added (a,c) to P. It is also possible that a bird flew from a to b to c to d and she only witnessed a and d, and added (a,d) to P , etc. To sum up, she knows that P contains all the edges of G and that P might contain some other edges (a,b) for which there is a path from a to b in G (note that 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. To be warned of the arrival of birds on T, she would also like to install detectors on the trees where the birds can come from (i.e. the trees T′ such that there is an edge ( T′,T) in G ). As detectors are not cheap, she only wants to install detectors on the trees T′ for which she is sure that (T′,T) belongs to G.

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

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

The next M lines describe the edges of the graph P. Each contains two space-separated integers a and b (0≤a, b

Limits

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

Sample Explanation 2

The graph corresponding to this example is depicted below. For the same reason as in Sample 1, the node 0 does not belong to S(2) while 1 does. The nodes 3 and 5 do not belong to S(2) because we do not have edges (3, 2) or (5, 2). Finally 4 belongs to S(2) because all paths from 4 to 2 use the edge (4, 2).

题意:给出多条路径,问到达根节点的路径只有一条的点的个数并输出对应点

思路:

1.会很自然的想到建立反向图,把题意转化成根节点出发到达某一点的路径个数只有一条的点及个数。
2.但是枚举每个点跑dfs会爆内存,所以只能用bfs,先将所有和根节点相连的点map记录一下,然后从这些点开始跑bfs,往外松弛边,遇到一个点就vis[i]++,代表有一条路到i, 然后跑完bfs后再倒回去看和根节点直接相连的点,到达他们的路径个数是否为1,是的话就记录并输出,不是的话就舍弃

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define maxn 100000+5
using namespace std;
int head[maxn],pnt[maxn],nxt[maxn],e=0;
int head1[maxn],pnt1[maxn],nxt1[maxn],e1=0;
vector<int> lst;

void addedge(int u,int v)
{
    pnt[e]=v;       //当前以u为顶点,c为边长的,到v的一条边
    nxt[e]=head[u];     //下一个其实是前一个
    head[u]=e++;        //当前边编号
}

void addedge1(int u,int v)
{
    pnt1[e]=v;       //当前以u为顶点,c为边长的,到v的一条边
    nxt1[e]=head1[u];     //下一个其实是前一个
    head1[u]=e1++;        //当前边编号
}

inline int read()
{
     int x = 0;
     char ch = getchar();
     while(ch<'0'||ch>'9')  ch = getchar();
     while(ch>='0'&&ch<='9')  x = (x<<3) + (x<<1) + ch - '0', ch = getchar();
     return x;
}

map<int,int> vis;
int n,m,root;
int flag = 1;
map<int,int> mymap;

void bfs()
{  queue<pair<int,int> > q;
    for(auto it = mymap.begin();it!=mymap.end();it++)
    q.push(make_pair(it->first,it->first));

    while(!q.empty())
    {
        int now = q.front().first;
        int fa = q.front().second;
        q.pop();
        if(vis[now]>=3)  continue;
        if(now!=fa||!vis[now]) vis[now] ++;     //如果是源点第一次出现或者当前点不是源点就vis ++。这样的话从一个源点出发
        else continue;
        for(int i =head[now]; i!=-1; i = nxt[i])
        {
                if(pnt[i]==root)  continue;
                q.push(make_pair(pnt[i], fa));
        }
    }

}

int main()
{
    ios::sync_with_stdio(false);
    n = read(), m = read(), root = read();
    for(int i=0;i<=n;i++) head[i] = -1 ;
    for(int i=1; i<=m; i++)
    {
        int x,y;
        x = read();
        y = read();
        if(y==root)  mymap[x]=1;
         addedge(y,x);
    }
    int ans = 0;
    bfs();
    for(auto it = mymap.begin();it!=mymap.end();it++)
    if(vis[it->first]==1) lst.push_back(it->first), ans++;
    sort(lst.begin(),lst.end());
    cout<<ans<<endl;
      for(auto it = lst.begin(); it!=lst.end(); it++)
     cout<<*it<<endl;
    return 0;
}

你可能感兴趣的:(队列,校队训练,BFS,BFS)