POJ 2186 Popular Cows

来源:互联网 发布:centos 6.3 32位下载 编辑:程序博客网 时间:2024/05/12 15:16

题目大意:给定m条有向边,求出有多少点,以任意一个点为起始点时都能到达。

解题思路:Tarjan.

自己做了一个特别渣的Tarjan类,Tarjan题直接套模板就好了。

#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <algorithm>using namespace std;#define MAXN 10100#define MAXM 50100struct PPP{       int point,next,val;};class Link{      public:             int now[MAXN];             struct PPP link[MAXM];             void insert(int a,int b)             {                 tail++;                 link[tail].point = b;                 link[tail].next = now[a];                 now[a] = tail;             }             void insert(int a,int b,int c)             {                 tail++;                 link[tail].point = b;                 link[tail].val = c;                 link[tail].next = now[a];                 now[a] = tail;             }             void clear()             {                  memset(now,0,sizeof(now));                  memset(link,0,sizeof(link));                  tail = 0;             }      private:              int tail;};int d[MAXN];int n,m;class Tarjan{      private:              int low[MAXN],dfn[MAXN];              int ins[MAXN],stack[MAXN],belong[MAXN];              int deep,top;void dfs(int u){     int v;     deep++;     low[u] = deep;     dfn[u] = deep;     stack[++top] = u;     ins[u] = 1;     for (int i = list1.now[u] ; i != 0 ; i = list1.link[i].next)     {         v = list1.link[i].point;         if (!dfn[v]) {                       dfs(v);                       low[u] = min(low[u],low[v]);//low[u]<low[v]?low[u]:low[v];                      }                 else {                       if (ins[v]) {                                    low[u] = min(low[u],dfn[v]);//low[u]<dfn[v]?low[u]:dfn[v];                                   }                      }     }     if (low[u] == dfn[u]) {                            length++;                            do                            {                                   v = stack[top--];                                   belong[v] = length;                                   ins[v] = 0;                            }while (u != v);                           }}void rebuild(){     //新表对于权值的含义      for (int i = 1 ; i <= n ; i ++) weight[belong[i]] ++;     for (int u = 1 ; u <= n ; u ++)     {         for (int e = list1.now[u] ; e != 0 ; e = list1.link[e].next)         {             int v = list1.link[e].point;             if (belong[u] != belong[v])             {                list2.insert(belong[u],belong[v],weight[belong[u]]);             }         }     }}      public:             int weight[MAXN];             int length;             Link list1,list2;             void clear()             {                  list1.clear();                  list2.clear();                  memset(low,0,sizeof(low));                  memset(dfn,0,sizeof(dfn));                  memset(ins,0,sizeof(ins));                  memset(weight,0,sizeof(weight));                  memset(stack,0,sizeof(stack));                  memset(belong,0,sizeof(belong));                  deep = top = length = 0;             }             void work()             {                  for (int i = 1 ; i <= n ; i ++)                      if (!dfn[i]) {                                    dfs(i);                                   }                  rebuild();             }             void insert(int a,int b)       {list1.insert(a,b);}             void insert(int a,int b,int c) {list1.insert(a,b,c);}}tarjan;int main(){    int t;    int x,y;    while (scanf("%d%d",&n,&m) != EOF)    {          memset(d,0,sizeof(d));          tarjan.clear();          for (int i = 1 ; i <= m ; i ++)          {              scanf("%d%d",&x,&y);              tarjan.insert(x,y);          }          tarjan.work();          int ans = 0;          int boo = 0;          int temp;          for (int i = 1 ; i <= tarjan.length ; i ++)          {              temp = 0;              for (int j = tarjan.list2.now[i];j != 0 ; j = tarjan.list2.link[j].next)                  temp ++;              if (temp == 0) {                              ans += tarjan.weight[i];                              boo++;                             }          }          if (boo == 1) printf("%d\n",ans);                   else printf("0\n",ans);    }    return 0;}