强联通分量容易出错的地方

这个题强联通分量容易出错的地方我都出了 我把它记下来。。。

 

#include <iostream>

#include <cstdio>

#include <cstring>

#define clr(x) memset(x, 0, sizeof(x))

using namespace std;

 

const int maxn = 50005;

const int maxm = 50005;

 

struct Edge {

       int to, next;

}e[maxm];

int head[maxn], tot;

void add(int u, int v) {

       e[tot].to = v;

       e[tot].next = head[u];

       head[u] = tot++;

}

int min(int a, int b) {

       return a > b ? b : a;

}

int n, m;

int dfn[maxn], low[maxn], id[maxn], outd[maxn], s[maxn], ins[maxn];

int s_cnt, ans_cnt, cnt;

 

 

void init() {

       clr(head);

       clr(dfn); clr(low); clr(id);clr(outd); clr(ins);

       tot = 1;

       s_cnt = 0;

       ans_cnt = 0;

       cnt = 1;

}

 

void dfs(int u) {

       s[s_cnt++] = u;

       ins[u] = 1;

       for(int i = head[u]; i; i = e[i].next) {

              int v = e[i].to;

              if(!dfn[v]) {

                     dfn[v] = low[v] = cnt++;

                     dfs(v);

                     low[u] = min(low[u], low[v]);

              } else if(ins[v]){

                     low[u] = min(low[u], dfn[v]);

              }

       }

       if(dfn[u] == low[u]) {

              ans_cnt++;

              int x;

              do {

                     x = s[--s_cnt];

                     ins[x] = 0;

                     id[x] = ans_cnt;

              } while(x != u);

       }

}

                    

int main() {

       int x, y;

       while(EOF != scanf("%d %d",&n, &m) ) {

              init();

              for(int i = 1; i <= m; i++) {

                     scanf("%d %d",&x, &y);

                     add(x, y);

              }

              for(int i = 1; i <= n; i++) {

                     if(!dfn[i]) {

                            dfn[i] = low[i] = cnt++;

                            dfs(i);

                     }

              }

              if(ans_cnt == 1) {

                     printf("%d\n", n);

                     continue;

              }

              for(int i = 1; i <= n; i++) {

                     for(int j = head[i]; j; j = e[j].next) {

                            int k = e[j].to;

                            if(id[i] != id[k])

                                   outd[id[i]]++;

                     }

              }

              int flag = 0;

              for(int i = 1; i <= ans_cnt; i++) {

                     if(outd[i] == 0) {

                            if(flag == 0) flag = i;

                            else {

                                   flag = 0;

                                   break;

                            }

                     }

              }

              if(flag == 0) {

                     puts("0");

              } else {

                     int sum = 0;

                     for(int i = 1; i <= n; i++) {

                            if(id[i] == flag) {

                                   sum++;

                            }

                     }

                     printf("%d\n", sum);

              }

       }

       return 0;

}

posted @ 2015-03-22 11:38  悠悠我心。  阅读(146)  评论(0编辑  收藏  举报