看看就发现了是道一眼题、、然后蒟蒻写了1h、、

先tarjan,然后缩点重新建图,最后扫一遍就可以了、、

(为什么加inline比不加要慢、、为什么调用全局变量比开局部变量要慢、、都是开O2的原因嘛!!!>_<)

 

  1 /**************************************************************
  2     Problem: 1051
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:48 ms
  7     Memory:2132 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <algorithm>
 12  
 13 using namespace std;
 14 const int N = 10005;
 15 const int M = 50005;
 16 struct edges{
 17     int next, to;
 18 }e[M], E[M];
 19 int n, m;
 20 int first[N], FIRST[N], tot, TOT;
 21 int low[N], dfn[N], s[N], w[N], cnt, top;
 22 int Cnt[N], num;
 23 bool vis[N], inq[N];
 24  
 25 inline int read(){
 26     int x = 0;
 27     char ch = getchar();
 28     while (ch < '0' || ch > '9')
 29         ch = getchar();
 30          
 31     while (ch >= '0' && ch <= '9'){
 32         x = x * 10 + ch - '0';
 33         ch = getchar();
 34     }
 35     return x;
 36 }
 37  
 38 inline void add_edge(int x, int y){
 39     e[++tot].next = first[x];
 40     first[x] = tot;
 41     e[tot].to = y;
 42 }
 43  
 44 inline void ADD_EDGE(int x, int y){
 45     E[++TOT].next = FIRST[x];
 46     FIRST[x] = TOT;
 47     E[TOT].to = y;
 48 }
 49  
 50 void DFS(int p){
 51     low[p] = dfn[p] = ++cnt;
 52     vis[p] = inq[p] = 1;
 53     s[++top] = p;
 54     int x, y;
 55     for (x = first[p]; x; x = e[x].next)
 56         if (!vis[(y = e[x].to)]){
 57             DFS(y);
 58             low[p] = min(low[p], low[y]);
 59         }else
 60         if (inq[y]) low[p] = min(low[p], dfn[y]);
 61     if (low[p] == dfn[p]){
 62         ++num, y = 0;
 63         while (y != p){
 64             inq[    (y = s[top--])] = 0;
 65             w[y] = num;
 66             ++Cnt[num];
 67         }
 68     }
 69 }
 70  
 71 void rebuild_graph(){
 72     int x, y; 
 73     for (int i = 1; i <= n; ++i)
 74         for (x = first[i]; x; x = e[x].next)
 75             if (w[i] != w[(y = e[x].to)])
 76                 ADD_EDGE(w[i], w[y]);
 77 }
 78  
 79 void tarjan(){
 80     for (int i = 1; i <= n; ++i)
 81         if (!vis[i]) DFS(i);
 82     rebuild_graph();
 83 }
 84  
 85 int work(){
 86     int res = 0;
 87     for (int i = 1; i <= num; ++i)
 88         if (!FIRST[i]){
 89             if (res) return 0;
 90             else res = Cnt[i];
 91         }
 92     return res;
 93 }
 94  
 95 int main(){
 96     n = read(), m = read();
 97     int X, Y;
 98     for (int i = 1; i <= m; ++i){
 99         X = read(), Y = read();
100         add_edge(X, Y);
101     }
102     tarjan();
103     printf("%d\n", work());
104     return 0;
105 }
View Code

 

posted on 2014-10-23 09:53  Xs酱~  阅读(164)  评论(0编辑  收藏  举报