1239D. Catowice City(强连通分量缩点)

每个人有一只猫

请你确定x和y

使得x+y=n,同时x个人不认识y只猫

结论1:对于每组人和猫,必选其一

首先,当我们选择一个人的时候,他自己养的猫和认识的猫一定不能选

根据结论1就必须选择他认识的猫的主人,否则会导致人数不够

由于认识关系是单向的,所以是一张有向图

选择一个人之后必须选择它的所有出边

结论2:一整个强连通分量必选

那么先强连通分量缩点,然后形成一个DAG,在DAG上找一个出度为0的点作为x,剩下的作为y即可

 

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+100;
int n,m,t;
vector<int> g[maxn];
int low[maxn],dfn[maxn],cnt,scc,pos[maxn];
stack<int> st;
void tj (int x) {
    low[x]=dfn[x]=++cnt;
    st.push(x);
    for (int y:g[x]) {
        if (!low[y])  {
            tj(y);
            low[x]=min(low[x],low[y]);
        }
        else if (!pos[y]) {
            low[x]=min(low[x],dfn[y]);
        } 
    }
    if (low[x]==dfn[x]) {
        scc++;
        while (1) {
            int u=st.top();
            st.pop();
            low[u]=low[x];
            pos[u]=scc;
            if (u==x) break;
        }
    }
}
int in[maxn],out[maxn];
int x[maxn],y[maxn];
int main () {
    scanf("%d",&t);
    while (t--) {
        scanf("%d%d",&n,&m);
        cnt=scc=0;
        while (st.size()) st.pop(); 
        for (int i=1;i<=n;i++) pos[i]=dfn[i]=low[i]=out[i]=0;
        for (int i=1;i<=n;i++) g[i].clear();
        for (int i=1;i<=m;i++) {
            scanf("%d%d",x+i,y+i);
            if (x[i]==y[i]) continue;
            g[x[i]].push_back(y[i]);
        }
        for (int i=1;i<=n;i++) if (!low[i]) tj(i);
        for (int i=1;i<=m;i++) if (pos[x[i]]!=pos[y[i]]) out[pos[x[i]]]++;
        if (scc==1) {
            printf("No\n");
            continue;
        }
        for (int i=1;i<=scc;i++) {
            if (out[i]==0) {
                int cnt=0;
                for (int j=1;j<=n;j++) cnt+=(pos[j]==i);
                printf("Yes\n%d %d\n",cnt,n-cnt);
                for (int j=1;j<=n;j++) if (pos[j]==i) printf("%d ",j);
                printf("\n");
                for (int j=1;j<=n;j++) if (pos[j]!=i) printf("%d ",j);
                printf("\n");
                break;
            } 
        }
    }
} 

 

posted @ 2021-02-02 15:08  zlc0405  阅读(88)  评论(0编辑  收藏  举报