K - Birdwatching Gym - 102501K (思维+图论+bfs)

题目链接

题意:给定一个有向图,给定其中一个顶点T,问有多少T0,满足所有T0->T的所有路径都经过边(T0->T) .

思路:这题首先要想到反向建图,把T0->T转化成T->T0。
然后我们再插入边的时候就可以直接把这些T0挑选出来,标记好。(下文用T0直接称呼这些点,因为答案只能在这些点产生)

接下来我们思考:如果从T出发,开始bfs(dfs因为数据太大会爆栈)并记录每个顶点访问次数,如果最终某个T0只被访问了1次,那无疑是符合要求的。
但是我们也会遇到1个特殊情况:
形如T->T0->T1->T2->T0 这种情况被访问了2次,但是依然符合题意,这该如何判断呢?
其实不难,这种情况下,可以把队列元素定义成结构体,用变量记录每个顶点在bfs树中的祖先,如果T0在第2次访问时祖先是T0,说明是符合要求的,可以把访问次数保持为1,方便输出答案。
但是如果仅仅这样朴素写,会mle/tle,因为N、E可以达到1e5。
我们可以给bfs来个类似剪枝操作,考虑到如果某个顶点访问次数超过了2,说明其出队超过2次,已经不需要再对其进行bfs扩展了。(之所以是2而不是1是因为可能存在环,环的入口点需要2次访问机会,而别的点扩展进入这个环也需要1次,所以当出现3的时候,就可以直接continue了)

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define INF 0x3f3f3f
#define LL long long
const int maxn=1e5+100;
struct node {int u,scr;};//顶点以及bfs时的最早祖先
int n,e,t;
vector<int> g[maxn];
bool start[maxn];//是否是直接相邻点
int vis[maxn];//记录每个顶点访问次数
void bfs()
{
    queue<node> q;
    for(int i=0;i<g[t].size();i++) q.push({g[t][i],g[t][i]});
    while(!q.empty())
    {
        node temp=q.front();
        q.pop();
        if(vis[temp.u]>2) continue; //剪枝 ,这里注释掉会mle/tle
        if(temp.u==temp.scr)
        {
            if(!vis[temp.u]) vis[temp.u]++;//第一步出发
            else continue;//此时的情况是,从出发点绕了一圈回来了,就不需要再bfs下去了
        }
        else vis[temp.u]++;//从别的start点开始bfs访问到了,就直接vis++,这里筛掉了一些不符合要求的T0
        for(auto i:g[temp.u])
        {
            if(i!=t) q.push({i,temp.scr});
        }
    }
}
int main()
{
//    ios::sync_with_stdio(false);
//    cin.tie(0);
//    cout.tie(0);
    scanf("%d%d%d",&n,&e,&t);
    for(int i=1;i<=e;i++)
    {
        int v1,v2;
        scanf("%d%d",&v1,&v2);
        g[v2].push_back(v1);
        if(v2==t) start[v1]=true;
    }
    bfs();
    vector<int> ans;
    for(int i=0;i<n;i++)
    {
        if(start[i] && vis[i]<=1) ans.push_back(i);
    }
    printf("%d\n",ans.size());
    for(int i=0;i<ans.size();i++) printf("%d\n",ans[i]);
    system("pause");
    return 0;
}

你可能感兴趣的:(图论,队列,图论,bfs)