Applese 的QQ群(二分+dfs)

链接:https://ac.nowcoder.com/acm/contest/330/F
来源:牛客网
 

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

Applese 有一个QQ群。在这个群中,大家互相请教问题。如 b 向 a 请教过问题,就把 a 叫做是 b 的"老板"。这样一个群中就会有很多老板。


同时规定:如果 a 是 b 的老板,b 是 c 的老板,那么 a 也是 c 的老板。

为了不破坏群里面和谐交流的氛围,Applese 定了一个群规:不允许出现 a 既是 b 的老板, b 又是 a 的老板。

你需要帮助 Applese 判断大家是否遵守了群规。

输入描述:

第一行两个整数 n, m,表示群里的人数以及请教问题的数量。
接下来 m 行,每行两个整数 a, b,表示 a 是 b 的"老板",即 b 向 a 请教了一个问题。
注:无论是否违反了群规,a 都会成为 b 的老板。

输出描述:

对于每次提问,输出一行"Yes"表示大家都遵守了群规,反之输出"No"。

示例1

输入

复制

4 4
1 2
2 3
3 1
1 4

输出

复制

Yes
Yes
No
No

备注:

1≤n≤10^5,1≤n≤10^5
1≤m≤2⋅10^5,1≤m≤2⋅10^5
1≤a,b≤n

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
using namespace std;
typedef long long ll;
int n,m;
struct edge{
    int x;
    int y;
    int nex;
}e[200005];
int cnt,head[100005],fr[200005],to[200005],in[100005],que[100005],vis[100005],tim,f[100005];
void adde(int xx,int yy){
    e[cnt].x=xx;
    e[cnt].y=yy;
    e[cnt].nex=head[xx];
    in[yy]++;
    head[xx]=cnt++;
}
bool dfs(int x){
    if(vis[x]==tim)return true;
    if(f[x])return false;
    f[x]=1;
    vis[x]=tim;
    for(int i=head[x];i!=-1;i=e[i].nex){
        int v=e[i].y;
        //vis[]
        if(dfs(v))
            return true;
        
    }
    vis[x]=0;
    return false;
}

bool check(int x){
    cnt=0;
    tim=0;
  //  cout<<x<<"#####";
    memset(head,-1,sizeof(head));
    memset(vis,0,sizeof(vis));
    memset(f,0,sizeof(f));
    //memset(in,0,sizeof(in));
    for(int i=1;i<=x;i++){
        adde(fr[i],to[i]);
  
    }
    for(int i=1;i<=n;i++){
        tim++;
        if(!f[i]&&dfs(i)){
            return false;
        }
          
    }return true;
    //return topo();
}
  
int main()
{
    cin >> n >> m;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&fr[i],&to[i]);
    }
    int l=1;
    int r=m;
    int ans=0;
    while(l<=r){
        int mid=(l+r)/2;
        if(check(mid)){
            ans=mid;
            l=mid+1;
        }
        else{
            r=mid-1;
        }
    }
    for(int i=1;i<=m;i++){
        if(i<=ans){
            printf("Yes
");
        }
        else{
            printf("No
");
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Staceyacm/p/10781815.html