codeforces 1239D

思路:一個點選,相關的點也必須選就是直白的2-sat模型。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000005;
const int maxm = 1000005;
int he[maxn],ver[maxm],ne[maxm],tot;
void add( int x,int y ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
}
int st[maxn],ins[maxn],c[maxn],dfn[maxn],low[maxn],top,num,cnt;
vector<int> scc[maxn];
void tarjan( int x ){
    dfn[x] = low[x] = ++num;
    st[++top] = x;ins[x] = 1;
    for( int cure = he[x];cure;cure = ne[cure] ){
        int y = ver[cure];
        if( !dfn[y] ){
            tarjan(y);
            low[x] = min( low[x],low[y] );
        }else if( ins[y] ){
            low[x] = min( low[x],dfn[y] );
        }
    }
    if( dfn[x] == low[x] ){
        cnt++;int cur;
        do{
            cur = st[top--];ins[cur] = 0;
            c[cur] = cnt;scc[cnt].push_back(cur);
        }while(x != cur);
    }
}
void init(int n){
    top = num = cnt = 0;
    memset( dfn,0,sizeof(int)*(n+1) );
    for( int i = 1;i <= n;i++ ) scc[i].clear();
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n,m;
        scanf("%d%d",&n,&m);
        tot = 1;
        memset( he,0,sizeof(int)*(n+1) );
        init(n);
        for( int x,y,i = 1;i <= m;i++ ){
            scanf("%d%d",&x,&y);
            add(x,y);
        }
        for( int i = 1; i <= n;i++ ){
            if(!dfn[i])
                tarjan(i);
        }
        if( cnt == 1 ){
            puts("No");
            continue;
        }
        puts("Yes");
        printf("%d %d\n",scc[1].size(),n-scc[1].size());
        for( int i = 0;i < scc[1].size();i++ ){
            printf("%d ",scc[1][i]);
        }
        puts("");
        for( int i = 2;i <= cnt;i++ ){
            for( int j = 0;j < scc[i].size();j++ ){
                printf("%d ",scc[i][j]);
            }
        }
        puts("");
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章