tarjan

#include <bits/stdc++.h>
#define MAXN 400010
using namespace std;
vector<int>v[MAXN];
bool sign[MAXN];
int dfn[MAXN],low[MAXN];
pair<int,int>belong[MAXN];
int num=0;
int tot=0;
int curr=0;
stack<int>sta;
void tarjan(int a/*,int pre*/)
{
    sta.push(a);
    sign[a]=true;
    dfn[a]=low[a]=++curr;
    for(int i=0;i<v[a].size();i++)
    {
        int b=v[a][i];
        if(!sign[b])
        {
            tarjan(b/*,a*/);
            low[a]=min(low[a],low[b]);
        }
        else //if(b!=pre)
            low[a]=min(low[a],dfn[b]);//感觉这地方的dfn[b]可以替换成low[b]
    }
    if(dfn[a]==low[a])
    {
        while(sta.top()!=a)
        {
            belong[num++]=make_pair(sta.top(),tot);
            sta.pop();
        }
        belong[num++]=make_pair(sta.top(),tot++);
        sta.pop();
    }
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int a,b;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&a,&b);
        v[a].push_back(b);
    }
    for(int i=1;i<=n;i++)
        if(!sign[i])
            tarjan(i/*,i*/);
    if(n)
        printf("%d",belong[0].first);
    for(int i=1;i<num;i++)
    {
        if(belong[i].second==belong[i-1].second)
            printf(" %d",belong[i].first);
        else printf("
%d",belong[i].first);
    }
    if(n)
        printf("
");
    return 0;
}

如果去掉注释符号就是双向边的.

原文地址:https://www.cnblogs.com/lthb/p/6031468.html