题解【[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() ;
}
posted @ 2019-02-16 16:16  tyqtyq~!  阅读(122)  评论(0编辑  收藏  举报