poj 1236 tarjan

缩点是求联通问题的基本操作qaq

注意特判原来就联通的情况

---

#include <iostream>
#include <math.h>
#include <string.h>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <algorithm>
#include <cstdio>
#include <set>
using namespace std;
int index=0,top=0,scc=0,n,vis[500000],stoc[500000],low[500000],dfn[500000],head[500000],belong[500000],rd[500000],cd[500000];
struct lys{
    int from,to,nex;
}edge[500009];
int cnt=0;
void add(int from,int to)
{
    cnt++;
    edge[cnt].from=from;
    edge[cnt].to=to;
    edge[cnt].nex=head[from];
    head[from]=cnt;
}
void tarjan(int x)
{
    index++;
    low[x]=dfn[x]=index;
    vis[x]=1;
    top++;
    stoc[top]=x;
    
    for(int i=head[x];i;i=edge[i].nex)
    {
        int to=edge[i].to;
        if(!dfn[to])
        {
            tarjan(to);
            low[x]=min(low[x],low[to]);
        }
        else if(vis[to])
        {
            low[x]=min(low[x],dfn[to]);
        }
    }
    int v;
    
    if(dfn[x]==low[x])
    {
        scc++;
        do{
            v=stoc[top];
            top--;
            vis[v]=0;
            belong[v]=scc;    
        }while(x!=v);
    }
}
int main()
{
    
    cin>>n;
    
    
    for(int i=1;i<=n;i++)
    { int x;
        while(1)
        {  
            scanf("%d",&x);
            if(!x) break;
            add(i,x); 
        }
    }
    
    
    for(int i=1;i<=n;i++)
    {
        if(!dfn[i])
        {
            tarjan(i);
        }
    }
    
    
    for(int i=1;i<=n;i++)
    {
        for(int j=head[i];j;j=edge[j].nex)
        {
            if(belong[edge[j].to]!=belong[edge[j].from])
            {
              rd[belong[edge[j].to]]++;
              cd[belong[edge[j].from]]++;    
            }
        }
    }
    
    int ans1=0,ans2=0;
    
    for(int i=1;i<=scc;i++)
    {
        if(rd[i]==0) ans1++;
        if(cd[i]==0) ans2++;
    }
    
    
    if(scc==1)
    {
        cout<<1<<endl<<0<<endl;
    }
    else cout<<ans1<<endl<<max(ans1,ans2)<<endl; 
}

 

posted @ 2021-11-03 14:38  liyishui  阅读(24)  评论(0编辑  收藏  举报