题解【[HAOI2006]受欢迎的牛】

切水题,写题解~

tarjan缩一波点,然后

  • 只有一个出度为0的点:他的size就是答案

  • 有多个初度为0的点:无解,0个

因为是强联通分量,所以肯定有出度为0的点,否则——就是你tarjan写挂了~

\[Talk\;is\;free\;,\;show\;me\;the\;code\]

#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<algorithm>
#define MAXN 200000
using namespace std ;
inline void read(int &x) {
    char ch=getchar();
    int s=0,f=1;
    while (!(ch>='0'&&ch<='9')) {
        if (ch=='-') f=-1;
        ch=getchar();
    }
    while (ch>='0'&&ch<='9') {
        s=(s<<3)+(s<<1)+ch-'0';
        ch=getchar();
    }
    x=s*f;
}
vector<int> edge[MAXN] ;
int ins[MAXN] , low[MAXN] , dfn[MAXN] ;
int tot , whr[MAXN] ; 
vector<pair<vector<int>,vector<int> > > scc ;
int deg[MAXN] ;
int n , m ;
void add(int u,int v){
    edge[u].push_back(v) ;
}
void print(stack<int> s){
    vector<int> sns ; sns.clear() ;
    while(!s.empty()){
        cerr<<s.top()<<" " ; s.pop() ;
    }
    cerr<<endl ;
}
stack<int> idx ;
vector<int> ptpuntil(int v , int wr){
    //print(idx) ;
    vector<int> nodes ;
    while((!idx.empty())&&idx.top()!=v) 
        nodes.push_back(idx.top()) , whr[idx.top()] = wr , idx.pop() ;
    nodes.push_back(idx.top()) , whr[idx.top()] = wr , idx.pop() ;
    return nodes ;
}

int totally = 1 ;
void tarjan(int node){
    dfn[node] = low[node] = ++totally ; ins[node] = 1 ; idx.push(node) ;
    for(auto& i:edge[node]){
        if(dfn[i]==0){
            tarjan(i) ;
            low[node] = min(low[node] , low[i]) ;
        }
        else if(ins[node]==1){
            low[node] = min(low[node] , dfn[i]) ;
        }
    }
    if(dfn[node]==low[node]){
        //cout<<"NODE "<<node<<endl ;
        scc.push_back(make_pair(ptpuntil(node,scc.size()),vector<int>())) ;
    }
}
void _add(int a,int b){
    if(a!=b) scc[a].second.push_back(b) ;
} 
void join(){
    //cerr<<"JOIN WORKS!"<<endl ;
    //cerr<<"n = "<<n<<endl ;
    for(int i=1;i<=n;++i) 
        for(auto& j : edge[i]) 
            _add(whr[i],whr[j]) ;
    for(auto& i : scc) sort(i.second.begin(),i.second.end()) , unique(i.second.begin(),i.second.end()) ;
}
void print(vector<int> V){
    for(auto& i : V) cerr<<i<<" " ; 
}
void print(vector<pair<vector<int> , vector<int> > > V){
    int m = 0 ;
    for(auto& i : V){
        cerr<<"Vector No."<<++m<<":\n\tfirst :" ;
        print(i.first) ;
        cerr<<"\n\tsecond:" ;
        print(i.second) ;
        cerr<<endl ;
    }
} 
void answer(){
    join() ;
    //print(scc) ;
    vector<int> zrs ;
    zrs.clear() ;
    for(int i=0;i<scc.size();++i){
        if(!scc[i].second.size()) zrs.push_back(i) ;
        //cout<<"PUSH "<<i<<endl ;
    }
    if(zrs.size()>1) printf("0\n") ;
    else {
        printf("%d\n",scc[*zrs.begin()].first.size()) ;
    }
}
int main(){
    read(n) , read(m) ;
    for(int i=1;i<=m;++i){
        int x , y ; read(x) , read(y) , add(x,y) ;
    }
    for(int i=1;i<=n;++i){
        if(!dfn[i]) totally = 0 , tarjan(i) ;
    }
    answer() ;
}

猜你喜欢

转载自www.cnblogs.com/tyqtyq/p/10388124.html
今日推荐