强连通分量Kosaraju

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
const int maxn=1e5+5;
const int maxm=2e5+5;
inline int read(){
    int a = 0; bool b = 1; char x = getchar();
    while(x<'0'||'9'<x){
        if(x=='-')b=0;
        x=getchar();
    }
    while('0'<=x && x<='9'){
        a=(a<<3)+(a<<1)+x-'0';
        x=getchar();
    }
    return b ? a : -a ;
}
int n,m;
int first[maxn][2],next[maxm][2],to[maxm][2],end[maxn];
int edge_count[2];
inline void add(int x,int y,bool b){
    edge_count[b]++;
    to[ edge_count[b] ][b]=y;
    next[ edge_count[b] ][b]=first[x][b];
    first[x][b]=edge_count[b]; 
}
int vis[maxn];
int Time=0;//时间戳 
void dfs_one(int x){
    vis[x]=1;
    for(int i=first[x][0];i;i=next[i][0]){
        if(!vis[ to[i][0] ])dfs_one(to[i][0]);
    }
    end[++Time]=x;
}
int temp=0,cnt[maxn];
void dfs_two(int x){
    vis[x]=temp;
    cnt[temp]++;
    for(int i=first[x][1];i;i=next[i][1]){
        if(vis[ to[i][1] ])continue;
        dfs_two(to[i][1]);
    }
}
//0->正向 ,1->反向 
int main()
{
    n=read();m=read();
    for(int i=1,a,b;i<=m;i++){
        a=read();b=read();
        add(a,b,0);add(b,a,1);
    }
    for(int i=1;i<=n;i++){if(!vis[i])dfs_one(i);}
    memset(vis,0,sizeof(vis));
    for(int i=n;i;i--){
        if(vis[ end[i] ])continue;
        temp++;
        dfs_two(end[i]);
    }
    for(int i=1;i<=n;i++){
        if(cnt[ vis[i] ]>1)printf("T\n");
        else printf("F\n");
    }
    return 0;
}

 

posted @ 2019-04-23 21:07  Tj1  阅读(120)  评论(0编辑  收藏  举报