[CODEVS 1332] 上白泽慧音 (Tarjan)

本文介绍了一种使用Tarjan算法寻找图中点数最多的强连通分量的方法。通过具体的代码实现,详细展示了如何利用Tarjan算法进行点双连通性和强连通分量的搜索,最终找到最大的强连通分量。

超裸Tarjan求点数最多的强连通分量 我这个蒟蒻都觉得没啥好写了 复习板子用
传送门

/*
作者:ymzQwQ
题目:p1332 上白泽慧音
*/
#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
using namespace std;
const int N=5001,M=50001;
int n,m,x,y,z,color[N],ans,sum[N],num,dfn[N],low[N],clonow;
bool b[N];
vector<int> a[N];
stack<int> h;

int Min(int x,int y) { return x<y?x:y; }

void tarjan(int x){
    dfn[x]=++num;low[x]=num;b[x]=1;h.push(x);
    for(int i=1;i<=a[x][0];i++){
        int temp=a[x][i];
        if (!dfn[temp]) tarjan(temp),low[x]=Min(low[x],low[temp]);
         else if (b[temp]) low[x]=Min(low[x],low[temp]);
    }
    if (dfn[x]==low[x]){
        b[x]=0;color[x]=++clonow;sum[clonow]++;
        while(h.top()!=x){
            int temp=h.top();
            b[temp]=0;color[temp]=clonow;
            h.pop();sum[clonow]++;
        }
        h.pop();
        if (sum[clonow]>sum[ans]) ans=clonow;
    }
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) a[i].push_back(0);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&x,&y,&z);
        a[x].push_back(y);++a[x][0];
        if (z==2) a[y].push_back(x),++a[y][0];
    }
    for(int i=1;i<=n;i++) if (!dfn[i]) tarjan(i);
    printf("%d\n",sum[ans]);
    for(int i=1;i<=n;i++) if (color[i]==ans) printf("%d ",i);
    return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值