[BZOJ] 1051: [HAOI2006]受欢迎的牛

1051: [HAOI2006]受欢迎的牛

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 6342  Solved: 3322
[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

 

Analysis

首先强连通分量缩点,于是这个图肯定成为一个DAG

出度为零的强连通分量就是答案啦

当然,如果有多个点为答案,那么就是错的,受欢迎的牛只有0头

为啥?

 

Code

 1 #include<cstdio>
 2 #include<iostream>
 3 #define maxn 1000000
 4 using namespace std;
 5 
 6 int n,m,de[maxn],ret,ans;
 7 int dfn[maxn],low[maxn],TIM,stack[maxn],pos,COL,buck[maxn],color[maxn];
 8 bool vis[maxn];
 9 
10 struct edge{ int from,u,v; }e[maxn],E[maxn];
11 int tot,first[maxn],toT,firsT[maxn];
12 void insert(int u,int v){ tot++; e[tot].from = first[u]; e[tot].u = u; e[tot].v = v; first[u] = tot; }
13 void inserT(int u,int v){ toT++; E[toT].from = firsT[u]; E[toT].u = u; E[toT].v = v; firsT[u] = toT; }
14 void tarjan(int now){
15     dfn[now] = low[now] = ++TIM;
16     stack[pos++] = now; vis[now] = true;
17     for(int i = first[now];i;i = e[i].from){
18         int v = e[i].v;
19         if(!dfn[v]){
20             tarjan(v); low[now] = min(low[now],low[v]);
21         }else if(vis[v]) low[now] = min(low[now],dfn[v]);
22     }if(dfn[now] == low[now]){
23         COL++;
24         while(stack[pos-1] != now && pos){
25             buck[COL]++;
26             color[stack[pos-1]] = COL;
27             vis[stack[--pos]] = false;
28         }color[now] = COL; vis[now] = false; pos--; buck[COL]++;
29     }
30 }
31 
32 int main(){
33     scanf("%d%d",&n,&m);
34     
35     for(int i = 1;i <= m;i++){
36         int x,y; scanf("%d%d",&x,&y);
37         insert(x,y);
38     }for(int i = 1;i <= n;i++) if(!dfn[i]) tarjan(i);
39     
40     for(int i = 1;i <= tot;i++){
41         int u = e[i].u,v = e[i].v;
42         if(color[u] != color[v]){
43             inserT(color[u],color[v]);
44             de[color[u]]++;
45         }
46     }
47     
48     for(int i = 1;i <= COL;i++){
49         if(!de[i]) ret++,ans = buck[i];
50     }
51     
52     if(ret > 1) cout << 0;
53     else cout << ans;
54     
55     return 0;
56 }
qwq一遍A那才叫爽!

 

posted @ 2017-10-07 18:16  Leviaton  阅读(173)  评论(0编辑  收藏  举报