洛谷 P1726 上白泽慧音(强连通)

传送门


强连通裸题,跑tarjan找最大的环,每次记录第一次找到该点的时间(dfn)与该点不通过父亲能到达的最早的祖先(low),第一次找到时将该点入栈,对于该点没搜过的子节点,我们用子节点的low来更新该点的low,对于搜过的且还在栈中子节点,用它的dfn来更新我的low。
如果有一个节点的dfn==low,则说明该节点与该节点在栈中以上的所有节点构成了一个强联通分量,全部出栈并记录信息。

Code:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;

struct node{int y,next;}a[50010];
int n,m,len=0,top=0,id=0,tot;
int first[5010],dfn[5010],low[5010],belong[5010],size[5010],sta[5010];
bool vis[5010];
//dfn搜到的时间 low不通过父亲能去到的最早的祖先 sta模拟栈
//belong每个点属于哪个连通子图 size连通子图的大小 vis是否在栈中 

void ins(int x,int y){a[++len]=(node){y,first[x]};first[x]=len;}

void dfs(int x)
{
    dfn[x]=low[x]=++id;
    sta[++top]=x;
    vis[x]=true;
    for(int i=first[x];i;i=a[i].next)
    {
        int y=a[i].y;
        if(dfn[y]==-1)
        {
            dfs(y);
            low[x]=min(low[x],low[y]);
        }
        else if(vis[y]) low[x]=min(low[x],dfn[y]);
    }
    if(dfn[x]==low[x])
    {
        tot++;
        int i;
        do
        {
            i=sta[top--];
            ++size[belong[i]=tot];
            vis[i]=false;
        }while(i!=x);
    }
}

void tarjan()
{
    memset(dfn,-1,sizeof(dfn));
    memset(size,0,sizeof(size));
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=n;i++)
        if(dfn[i]==-1) dfs(i);
}

void print()
{
    int maxx=size[belong[1]];
    for(int i=2;i<=n;i++)
        if(size[maxx]<size[belong[i]]) maxx=belong[i];
    printf("%d\n",size[maxx]);
    for(int i=1;i<=n;i++)
        if(belong[i]==maxx) printf("%d ",i);
}

int main()
{
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++) 
    {
        int x,y,t;
        scanf("%d %d %d",&x,&y,&t);
        ins(x,y);
        if(t==2) ins(y,x);
    }
    tarjan();
    print();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值