tarjan求强连通+缩点——cf1248E

Posted zsben991126

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tarjan求强连通+缩点——cf1248E相关的知识,希望对你有一定的参考价值。

这题好像是DEF里最水的,,

/*
建图:如果a认识b,那么从a->b连一条边,将点分成两个集合A,B,没有从A->B的边 
求出强连通分量,再造一张新图,新图中任取一个的出度为0的点作为集合A即可
*/
#include<bits/stdc++.h>
using namespace std;
#define N 2000005

struct Edge{int to,nxt;}e[N<<1];
int head[N],tot,n,m;

int c[N],out[N],cnt;//新图的点个数,每个点的出度 
int ind,dfn[N],low[N],stk[N],top,ins[N];
void tarjan(int x){
    dfn[x]=low[x]=++ind;
    stk[++top]=x;ins[x]=1;
    for(int i=head[x];i!=-1;i=e[i].nxt){
        int y=e[i].to;
        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 y;
        do{
            y=stk[top--];
            ins[y]=0;
            c[y]=cnt;
        }while(x!=y);
    }
}

void init(){
    cnt=tot=ind=0;
    for(int i=0;i<=2*n;i++)
        low[i]=dfn[i]=ins[i]=out[i]=c[i]=0,head[i]=-1;
}
void add(int u,int v){
    e[tot].to=v;e[tot].nxt=head[u];head[u]=tot++;
}

int main(){
    int t;cin>>t;while(t--){
        cin>>n>>m;
        init();
        for(int i=1;i<=m;i++){
            int u,v;scanf("%d%d",&u,&v);
            if(u!=v)add(u,v);    
        }
        
        for(int i=1;i<=n;i++)
            if(!dfn[i])tarjan(i);
        
         for(int u=1;u<=n;u++)
            for(int i=head[u];i!=-1;i=e[i].nxt){
                int v=e[i].to;
                if(c[u]!=c[v])
                    out[c[u]]++;
            }
            
        int ans=0;
        for(int i=1;i<=cnt;i++)
            if(out[i]==0){ans=i;break;}
        if(ans==0||cnt==1){puts("No");continue;}
        
        puts("Yes");
        int cnta=0,cntb=0;
        for(int i=1;i<=n;i++)
            if(c[i]==ans)cnta++;
            else cntb++;
        cout<<cnta<<" "<<cntb<<
;
        for(int i=1;i<=n;i++)if(c[i]==ans)cout<<i<<" ";puts("");
        for(int i=1;i<=n;i++)if(c[i]!=ans)cout<<i<<" ";puts("");
    }
}
/*
9 21
1 7
5 7
4 8
1 1
4 4
7 3
3 3
6 3
6 6
5 5
7 7
8 2
9 2
3 1
8 8
9 9
2 2
1 5
6 7
2 6
6 4

*/

 

以上是关于tarjan求强连通+缩点——cf1248E的主要内容,如果未能解决你的问题,请参考以下文章

tarjan算法+缩点:求强连通分量 POJ 2186

P3387 模板缩点(Tarjan求强连通分量)

BZOJ10511051: [HAOI2006]受欢迎的牛 tarjan求强连通分量+缩点

hihoCoder#1185 : 连通性·三 tarjan求强联通分量 缩点 dfs/拓扑排序求路径和最大值

CF949C Data Center Maintenance Tarjan找强连通分量

tarjan——强连通分量+缩点