tarjan 受欢迎的牛

https://loj.ac/problem/10091

既然爱慕关系可以传递,那么将互相可达的某几个点缩成一个点,就能简化原图了,

那么很自然想到tarjan求强连通分量

那么就只需找到可以被所有缩点遍历到的那个缩点

再输出它所含的点数就行了

先用tarjan将所有联通分量进行缩点,缩点后考虑出度为0的点的个数:

(1)个数大于1的时候,显然不存在受欢迎的牛!

(2)个数等于0的时候,假设有一头牛X是受欢迎的,那么它必定有喜欢的牛Y,而它又收到牛Y的欢迎,说明存在环,不是DAG图,矛盾!

(3)个数等于1的时候,用数学归纳法推一下,有这样一个结论:出度为0的那个点可以被其它所有点到达

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
const int maxm=5e4+5;
int n, m, a, b, cnt, num, top, col;
int head[maxm];
int s[maxm];
int st[maxm]; 
int co[maxm];
int de[maxm];
int dfn[maxm], low[maxm];
using namespace std;
struct cow {
	int to;
	int next;
} edge[maxm];
void add(int x, int y) {
	cnt++;
	edge[cnt].to = y;
	edge[cnt].next = head[x];
	head[x] = cnt;
}
void tarjan(int u) {
	dfn[u] = low[u] = ++num;
	st[++top] = u;
	for (int i = head[u]; i; i = edge[i].next) {
		int v = edge[i].to;
		if (dfn[v] == 0) {
			tarjan(v);
			low[u] = min (low[u], low[v]);
		} else if(co[v] == 0) 
		    low[u] = min (low[u], low[v]);
	}
	if (low[u] == dfn[u]) {
		co[u] = ++col;
		++s[col];
		while (st[top] != u) {
			++s[col];
			co[st[top]] = col;
			--top;
		}
		--top;
	}
}
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= m; i++) {
		scanf("%d%d", &a, &b);
		add(b, a); //倒着存以最后统计出度而不是统计入度
	}
	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 = edge[j].next) {
	    	int v = edge[j].to;
	    	if (co[i] != co[v]) 
			    de[co[v]]++;
		}
	int ans = 0, u = 0;
	for (int i = 1; i <= col; i++) 
	    if(de[i] == 0) {
	    	ans = s[i];
	    	u++;
		}
	if(u == 1) 
	   printf("%d\n", ans);
	else  
       printf("0\n");
	return 0;
}
void tarjan(int 当前点)
{
    这个点的low=dfn=时间戳;
    将这个点入栈;
    标记这个点入栈;
    枚举这个点连接的所有边
    {
        如果目标点没有被访问过
        {
            tarjan(目标点);
            更新当前点的low; 
        }  
        如果目标点被访问过
        {
            更新当前点的low; 
        } 
    }
    如果当前点的low==dfn
    {
        将这个点及栈以上的点出栈,标记成一个强连通分量; 
        ans++; 
    } 
} 

猜你喜欢

转载自blog.csdn.net/syh8501/article/details/85376253
今日推荐