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 @   liyishui  阅读(25)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示