P2002 消息扩散题解

P2002 消息扩散

题目背景

本场比赛第一题,给个简单的吧,这 100 分先拿着。

题目描述

nnn 个城市,中间有单向道路连接,消息会沿着道路扩散,现在给出 nnn 个城市及其之间的道路,问至少需要在几个城市发布消息才能让这所有 nnn 个城市都得到消息。

输入格式

第一行两个整数 n,mn, mn,m,表示 nnn 个城市,mmm 条单向道路。

以下 mmm 行,每行两个整数 b,eb, eb,e 表示有一条从 bbbeee 的道路,道路可以重复或存在自环。

输出格式

一行一个整数,表示至少要在几个城市中发布消息。

输入输出样例 #1

输入 #1

5 4
1 2
2 1
2 3
5 1

输出 #1

2

说明/提示

【样例解释 #1】

样例中在 4,54, 54,5 号城市中发布消息。

【数据范围】

对于 20%20 \%20% 的数据,n≤200n \le 200n200
对于 40%40 \%40% 的数据,n≤2000n \le 2000n2000
对于 100%100 \%100% 的数据,1≤n≤1051 \le n \le {10}^51n1051≤m≤5×1051 \le m \le 5 \times {10}^51m5×105

思路

直接 tarjan 即可。
对于此题,tarjan 即可。

代码见下

#include<bits/stdc++.h>
using namespace std;
long long a,b;
long long n,m,aa,bb,dfn[200005],low[200005],st[200005],n2=0,ss=0,s2[200005],df[200005],fd[200005],fd2[200005],db=0,bd=0,de[200005];
vector<long long> v[200005];
inline void abc(long long a1){
    low[a1]=dfn[a1]=++n2;
    st[++st[200004]]=a1;
    de[a1]=1;
    //cout<<st[200004]<<" "<<st[st[200004]]<<endl;
    for(int i=0;i<v[a1].size();i++){
        long long tt=v[a1][i];
        if(de[tt]==1){
            low[a1]=min(low[a1],dfn[tt]);
        }
        else if(de[tt]==0){
            abc(tt);
            low[a1]=min(low[a1],low[tt]);
        }
    }
    if(low[a1]==dfn[a1]){
        ss++;
        s2[a1]=ss;
        df[ss]=1;
        while(st[st[200004]]!=a1){
            //cout<<st[200004]<<" "<<st[st[200004]]<<endl;
            s2[st[st[200004]]]=ss;
            de[st[st[200004]]]=-1;
            st[200004]--;
            df[ss]++;
        }
        //cout<<st[200004]<<" "<<st[st[200004]]<<" "<<a1<<endl;
        de[st[st[200004]]]=-1;
        st[200004]--;
    }
    //cout<<a1<<" "<<v[a1].size()<<" "<<st[200004]<<endl;
    return ;
}
int main(){
	cin>>n>>m;
    for(int i=1;i<=m;i++){
        cin>>aa>>bb;
        v[aa].push_back(bb);
    }
    for(int i=1;i<=n;i++){
        if(dfn[i]==0){
            //cout<<"ddddddddddddddddddddddddddd"<<i<<endl;
            abc(i);
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=0;j<v[i].size();j++){
            if(s2[i]!=s2[v[i][j]]){
                if(s2[i]==0){
                    //cout<<i<<endl;
                    //cout<<st[200004]<<endl;
                }
                fd[s2[v[i][j]]]++;
                fd2[s2[i]]++;
            }
        }
    }
    for(int i=1;i<=ss;i++){
        if(fd[i]==0){
            bd++;
        }
        if(fd2[i]==0){
            db++;
        }
    }
    if(ss==1){
        cout<<1<<endl;
        return 0;
    }
    cout<<bd<<endl;
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
long long a,b;
long long n,m,aa,bb,dfn[200005],low[200005],st[200005],n2=0,ss=0,s2[200005],df[200005],fd[200005],fd2[200005],db=0,bd=0,de[200005];
vector<long long> v[200005];
inline void abc(long long a1){
    low[a1]=dfn[a1]=++n2;
    st[++st[200004]]=a1;
    de[a1]=1;
    //cout<<st[200004]<<" "<<st[st[200004]]<<endl;
    for(int i=0;i<v[a1].size();i++){
        long long tt=v[a1][i];
        if(de[tt]==1){
            low[a1]=min(low[a1],dfn[tt]);
        }
        else if(de[tt]==0){
            abc(tt);
            low[a1]=min(low[a1],low[tt]);
        }
    }
    if(low[a1]==dfn[a1]){
        ss++;
        s2[a1]=ss;
        df[ss]=1;
        while(st[st[200004]]!=a1){
            //cout<<st[200004]<<" "<<st[st[200004]]<<endl;
            s2[st[st[200004]]]=ss;
            de[st[st[200004]]]=-1;
            st[200004]--;
            df[ss]++;
        }
        //cout<<st[200004]<<" "<<st[st[200004]]<<" "<<a1<<endl;
        de[st[st[200004]]]=-1;
        st[200004]--;
    }
    //cout<<a1<<" "<<v[a1].size()<<" "<<st[200004]<<endl;
    return ;
}
int main(){
	cin>>n>>m;
    for(int i=1;i<=m;i++){
        cin>>aa>>bb;
        v[aa].push_back(bb);
    }
    for(int i=1;i<=n;i++){
        if(dfn[i]==0){
            //cout<<"ddddddddddddddddddddddddddd"<<i<<endl;
            abc(i);
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=0;j<v[i].size();j++){
            if(s2[i]!=s2[v[i][j]]){
                if(s2[i]==0){
                    //cout<<i<<endl;
                    //cout<<st[200004]<<endl;
                }
                fd[s2[v[i][j]]]++;
                fd2[s2[i]]++;
            }
        }
    }
    for(int i=1;i<=ss;i++){
        if(fd[i]==0){
            bd++;
        }
        if(fd2[i]==0){
            db++;
        }
    }
    if(ss==1){
        cout<<1<<endl;
        return 0;
    }
    cout<<bd<<endl;
    return 0;
}
posted @ 2025-10-28 17:33  bz02_2023f2  阅读(2)  评论(0)    收藏  举报  来源