Tarjan缩点+建新图

详见代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define maxn 10010
#define ll long long
#define IL inline
#define clear(a) memset(a,0,sizeof a)

int n,m,tot1,tot2,num,cnt,top;
int first[maxn],head[maxn];
int dfn[maxn],low[maxn],stack[maxn],col[maxn];
struct edge{
    int from,to,nextx;
}e[maxn],ne[maxn];

void add1(int u,int v){
    tot1++;
    e[tot1].nextx=first[u];
    first[u]=tot1;
    e[tot1].to=v;
    e[tot1].from=u;
}

void add2(int u,int v){
    tot2++;
    ne[tot2].nextx=head[u];
    head[u]=tot2;
    ne[tot2].from=u;
    ne[tot2].to=v;
}

void tarjan(int u){
    dfn[u]=++num,low[u]=num;
    stack[++top]=u;
    for(int i=first[u];i;i=e[i].nextx){
        int v=e[i].to;
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(!stack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        col[u]=++cnt;
        while(stack[top]!=u){
            col[stack[top]]=cnt;
            top--;
        }
        top--;
    }
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        add1(a,b);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i])tarjan(i);
    for(int i=1;i<=m;i++){
        int x=e[i].from,y=e[i].to;
        if(col[x]!=col[y])
            add2(x,y);
    }
    return 0;
}

 

posted @ 2019-11-04 16:46  KGW_源  阅读(256)  评论(0编辑  收藏  举报
- Hide code