可达性_tarjan

链接: https://www.nowcoder.com/acm/contest/81/C
来源:牛客网

题目描述

给出一个 0 ≤ N ≤ 10 5 点数、0 ≤ M ≤ 10 5 边数的有向图,
输出一个尽可能小的点集,使得从这些点出发能够到达任意一点,如果有多个这样的集合,输出这些集合升序排序后字典序最小的。

输入描述:

第一行为两个整数 1 ≤ n, m ≤ 105,
接下来 M 行,每行两个整数 1 ≤ u, v ≤ 105 表示从点 u 至点 v 有一条有向边。
数据保证没有重边、自环。

输出描述:

第一行输出一个整数 z,表示作为答案的点集的大小;
第二行输出 z 个整数,升序排序,表示作为答案的点集。
示例1

输入

7 10
4 5
5 1
2 5
6 5
7 2
4 2
1 2
5 3
3 5
3 6

输出

2
4 7

     
#include<bits/stdc++.h>
using namespace std;

const int N=1e5+10;

int ne[N],p[N],h[N],j,dfn[N],cnt,b[N],t,s[N],M,a[N],low[N],f[N],in[N],ans[N],A;
int n,m;

void dfs(int x){
    dfn[x]=low[x]=++cnt;
    b[x]=1;
    s[++t]=x;
    int i;
    for(i=h[x];i;i=ne[i]){
        if(!dfn[p[i]]){
            dfs(p[i]);
            low[x]=min(low[x],low[p[i]]);
        }else if(b[p[i]]){
            low[x]=min(low[x],dfn[p[i]]);
        }
    }
    if(dfn[x]==low[x]){
        M++;
        a[M]=n;
        do{
            i=s[t--];
            f[i]=M;
            b[i]=0;
            a[M]=min(a[M],i);
        }while(i!=x);
    }
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        cin>>j>>p[i];
        ne[i]=h[j];
        h[j]=i;
    }
    for(int i=1;i<=n;i++)if(!dfn[i])dfs(i);
    for(int i=1;i<=n;i++)for(j=h[i];j;j=ne[j])
        if(f[p[j]]!=f[i])in[f[p[j]]]++;
    for(int i=1;i<=M;i++)if(!in[i])ans[++A]=a[i];
    sort(ans+1,ans+1+A);
    cout<<A<<endl;
    int i;
    for(i=1;i<A;i++)
    cout<<ans[i]<<" ";
    cout<<ans[i];
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值