[bzoj1051][HAOI2006]受欢迎的牛 Tarjan

xiaoxiao2021-02-27  156

1051: [HAOI2006]受欢迎的牛

Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 5456  Solved: 2904 [ Submit][ Status][ Discuss]

Description

  每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这 种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头 牛被所有的牛认为是受欢迎的。

Input

  第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可 能出现多个A,B)

Output

  一个数,即有多少头牛被所有的牛认为是受欢迎的。

Sample Input

3 3 1 2 2 1 2 3

Sample Output

1

HINT

100%的数据N<=10000,M<=50000

Source

[ Submit][ Status][ Discuss]



 没有什么好说的

#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> using namespace std; const int N = 10005; struct Edge{ int to,next; }e[N*5],ee[N*5]; int dfn[N],low[N],m,n; int id,scnt,cnt; int last[N],last2[N],q[N],top,belong[N],to[N],ans=0; bool inq[N]; void insert( int u, int v ){ e[++cnt].to = v; e[cnt].next = last[u]; last[u] = cnt; } void insert2( int u, int v ){ ee[++cnt].to = v; ee[cnt].next = last2[u]; last2[u] = cnt; } void tarjan( int x ){ int now = 0; dfn[x] = low[x] = ++id; q[++top] = x; inq[x] = 1; for( int i = last[x]; i; i = e[i].next ) if(!dfn[e[i].to]){ tarjan(e[i].to); low[x] = min(low[x],low[e[i].to]); } else if( inq[e[i].to] ) low[x] = min(low[x],dfn[e[i].to]); if( low[x] == dfn[x] ){ scnt++; while( now != x ){ now = q[top--]; inq[now] = 0; belong[now] = scnt; ++to[scnt]; } } } void rebuild(){ cnt = 0; for( int i = 1; i <= n; i++ ) for( int j = last[i]; j; j = e[j].next ) if( belong[e[j].to] != belong[i] ) insert2(belong[i],belong[e[j].to]); } int main(){ scanf("%d%d", &n, &m); for( int i = 1,u,v; i <= m; i++ ){ scanf("%d%d", &u, &v); insert(u,v); } for( int i = 1; i <= n; i++ ) if( !dfn[i] ) tarjan(i); rebuild(); for( int i = 1; i <= scnt; i++ ) if( !last2[i] ){ if( ans ){ans = 0; break;} else ans = to[i]; } printf("%d", ans); return 0; }

HOME Back

转载请注明原文地址: https://www.6miu.com/read-14547.html

最新回复(0)