洛谷 #2341. 受欢迎的牛

版权声明:转载请注明出处 https://blog.csdn.net/qq_41593522/article/details/84196598

题意

n只牛,有爱慕关系,问几只奶牛被所有牛爱(自恋的)

题解

先Tarjan缩点,然后统计大点出度

调试记录

统计的是大点出度

只能有一个出度为0

#include <cstdio>
#include <stack>
#include <cstring>
#define maxn 50005

using namespace std;

struct node{
	int to, next;
}e[maxn << 1];
int tot = 0, head[maxn];
void addedge(int u, int v){e[++tot] = (node){v, head[u]}; head[u] = tot;}

stack <int> s;
bool vis[maxn]; int color[maxn], val[maxn];
int Ctot = 0, dfn[maxn], low[maxn], Index = 0;
void Tarjan(int cur){
	s.push(cur);
	dfn[cur] = low[cur] = ++Index;
	vis[cur] = true;
	for (int i = head[cur]; i; i = e[i].next){
		if (!dfn[e[i].to]){
			Tarjan(e[i].to);
			low[cur] = min(low[cur], low[e[i].to]);
		}
		else if (vis[e[i].to]) low[cur] = min(low[cur], low[e[i].to]);
	}
	
	if (dfn[cur] == low[cur]){
		Ctot++; val[Ctot] = 0;
		while (s.top() != cur){
			val[Ctot]++;
			color[s.top()] = Ctot;
			vis[s.top()] = false;
			s.pop();
		}
		val[Ctot]++;
		color[s.top()] = Ctot;
		vis[s.top()] = false;
		s.pop();
	}
}

struct Q{
	int u, v;
}q[maxn];

int n, m;
int main(){
	scanf("%d%d", &n, &m);
	
	for (int i = 1; i <= m; i++){
		scanf("%d%d", &q[i].u, &q[i].v);
		addedge(q[i].u, q[i].v);
	}
	
	for (int i = 1; i <= n; i++)
		if (!dfn[i]) Tarjan(i);
		
	memset(e, 0, sizeof e);
	memset(head, 0, sizeof head);
	tot = 0;
	
	int OutDex[maxn];
	for (int i = 1; i <= m; i++)
		if (color[q[i].u] != color[q[i].v]) addedge(color[q[i].u], color[q[i].v]), OutDex[color[q[i].u]]++;
		
	int ans = 0;
	for (int i = 1; i <= Ctot; i++)
		if (!OutDex[i]){
			if (ans){
				printf("0\n");
				return 0;
			}
			ans += val[i];
		}
	
	printf("%d\n", ans);
	
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_41593522/article/details/84196598