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

来源:互联网 发布:模拟退火算法代码 编辑:程序博客网 时间:2024/05/04 23:45

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

原创粉丝点击