【HAOI 2006】 受欢迎的牛

【题目链接】

          点击打开链接

【算法】

            先用tarjan缩点,然后找出度为零的点,即可

【代码】

             

#include<bits/stdc++.h>
using namespace std;
#define MAXN 500010

struct Edge
{
		int to,nxt;
} e[MAXN];

int i,tot,ans,u,v,timer,top,cnt,n,m;
bool instack[MAXN];
int belong[MAXN],low[MAXN],dfn[MAXN],size[MAXN],
		head[MAXN],stk[MAXN],x[MAXN],y[MAXN],degree[MAXN];

template <typename T> inline void read(T &x)
{
    int f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}
template <typename T> inline void write(T x)
{
    if (x < 0)
    {
        putchar('-');
        x = -x;
    }
    if (x > 9) write(x/10);
    putchar(x%10+'0');
}
template <typename T> inline void writeln(T x)
{
    write(x);
    puts("");
}
inline void add(int u,int v)
{
		tot++;
		e[tot] = (Edge){v,head[u]};
		head[u] = tot;	
}
inline void tarjan(int u)
{
		int i,v;
		dfn[u] = low[u] = ++timer;
		instack[u] = true;
		stk[++top] = u;
		for (i = head[u]; i; i = e[i].nxt)
		{
				v = e[i].to;
				if (!dfn[v])
				{
						tarjan(v);
						low[u] = min(low[u],low[v]);
				} else 
				{
						if (instack[v]) 
								low[u] = min(low[u],dfn[v]);
				}
		}	
		if (dfn[u] == low[u])
		{
				cnt++;
				while (stk[top+1] != u)
				{
						instack[stk[top]] = false;
						belong[stk[top]] = cnt;
						size[cnt]++;
						top--;
				}
		}
}

int main() {
		
		read(n); read(m);
		for (i = 1; i <= m; i++)
		{
				read(x[i]); read(y[i]);
				add(x[i],y[i]);	
		}		
		for (i = 1; i <= n; i++)
				if (!dfn[i]) tarjan(i);
		for (i = 1; i <= m; i++)
		{
				if (belong[x[i]] != belong[y[i]])
						degree[belong[x[i]]]++;		
		}
		for (i = 1; i <= cnt; i++)
		{
				if (!degree[i]) 
				{
						if (ans) 
						{
								ans = 0;
								break;
						}
						ans = size[i];
				}
		}
		
		writeln(ans);
		
		return 0;
	
}

猜你喜欢

转载自blog.csdn.net/even_bao/article/details/80368416