P2863 [USACO06JAN] The Cow Prom S题解

P2863 [USACO06JAN] The Cow Prom S

题目描述

有一个 nnn 个点,mmm 条边的有向图,请求出这个图点数大于 111 的强连通分量个数。

输入格式

第一行为两个整数 nnnmmm

第二行至 m+1m+1m+1 行,每一行有两个整数 aaabbb,表示有一条从 aaabbb 的有向边。

输出格式

仅一行,表示点数大于 111 的强连通分量个数。

输入输出样例 #1

输入 #1

5 4
2 4
3 5
1 2
4 1

输出 #1

1

说明/提示

数据规模与约定

对于全部的测试点,保证 2≤n≤1042\le n \le 10^42n1042≤m≤5×1042\le m\le 5\times 10^42m5×1041≤a,b≤n1 \leq a, b \leq n1a,bn

思路

直接强连通分量即可。

代码见下

#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(df[i]>=2){
            bd++;
        }
    }
    // 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(df[i]>=2){
            bd++;
        }
    }
    // if(ss==1){
    //     cout<<1<<endl;
    //     return 0;
    // }
    cout<<bd<<endl;
    return 0;
}
posted @ 2025-10-28 17:28  bz02_2023f2  阅读(1)  评论(0)    收藏  举报  来源