P2341 [HAOI2006]受欢迎的牛

Description:

每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶
牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜
欢B,B喜欢C,那么A也喜欢C。牛栏里共有N 头奶牛,给定一些奶牛之间的爱慕关系,请你
算出有多少头奶牛可以当明星。

Analysis:

显然强连通分量里的点都互相喜欢,跑tarjan求强连通分量,统计每个强连通分量的出度,如果有一个强连通分量出度为0,则输出该强连通分量的大小。若同时存在多个强连通分量出度为0,则不满足题意,输出0。

Code:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<stack>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 10001;
const int maxm = 50005;
int s[maxn],top;
//stack<int> s;
struct edge{
	int next,to;
}e[maxm];
//	dfn[] := dfs序,low[] := 该点及其子树所能追溯的的最小的dfn值
//	scc[] := 属于哪个强连通分量,Scc[] := 强连通分量的大小
//	in[] := 强连通分量的入度,out[] := 强连通分量的出度
int head[maxn],dfn[maxn],low[maxn],scc[maxn],Scc[maxn],in[maxn],out[maxn],num_dfs,num_scc,num_edge,n,m,cnt,ans;
void tarjan(int u){
	dfn[u] = low[u] = ++num_dfs;
	s[++top] = u;
	//s.push(u);
	for(int i = head[u];i;i = e[i].next){
		int v = e[i].to;
		if(!dfn[v]){
			//如果v未访问,则继续递归 
			tarjan(v);
			low[u] = min(low[u],low[v]);
		}else{
			if(!scc[v])
				low[u] = min(low[u],dfn[v]);
		}
	}
	if(low[u] == dfn[u]){
		++num_scc;
		Scc[num_scc]++;
		scc[u] = num_scc;
		while(s[top] != u){
			Scc[num_scc]++;
			scc[s[top]] = num_scc;//同一个强连通分量的点放在栈中 
			--top;
		}
		--top;
	}
}
void add(int from,int to){
	e[++num_edge].next = head[from];
	e[num_edge].to = to;
	head[from] = num_edge;
}
int main(){ 
	scanf("%d %d",&n,&m); 
	for(int i = 1;i <= m;i++){
		int a,b;
		scanf("%d %d",&a,&b);
		add(a,b);
	}
	//tarjan找强连通分量 
	for(int i = 1;i <= n;i++){
		if(!dfn[i]) tarjan(i);
	}
	for(int i=1;i<=n;i++){
		for(int j=head[i];j;j=e[j].next){
			int t = e[j].to;
			//枚举原图中的两个相连的点,若不属于同一个强连通分量,则其入度、出度分别+1 
			if(scc[i] != scc[t])
				in[scc[t]]++,out[scc[i]]++;
		}
	}
	//if(scc[i]!=scc[t]) outd[belong[i]]++,ind[belong[t]]++;
	ans = 0;
	for(int i = 1;i <= num_scc;i++){
		if(!out[i]){
			if(ans){
				//如果存在多个出度为0的强连通分量,则无解 
				ans = 0;
				break;
			}
			else{
				ans = Scc[i];
			}
		}
	}
	printf("%d",ans);
	return 0;
}
岂能尽如人意,但求无愧我心
原文地址:https://www.cnblogs.com/Zforw/p/10611008.html