码迷,mamicode.com
首页 > 其他好文 > 详细

tarjan

时间:2016-11-04 20:33:04      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:return   print   scanf   vector   main   while   amp   pair   printf   

#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("\n%d",belong[i].first);
    }
    if(n)
        printf("\n");
    return 0;
}

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

tarjan

标签:return   print   scanf   vector   main   while   amp   pair   printf   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!