# poj2186Popular Cows

`#include <map>#include <set>#include <cmath>#include <queue>#include <stack>#include <cstdio>#include <string>#include <vector>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;const int MAXE = 22220, MAXV = 11110;struct Arc{    int dest;    Arc *next;    inline Arc() {}    inline Arc(const int &_dest, Arc *_next):dest(_dest), next(_next) {}}Npool[MAXE], *Nptr = Npool, *adj[MAXV];vector<int> com[MAXV];//存强连通分量的容器int n, m, dfn[MAXV], low[MAXV], belong[MAXV], index, cnt;//n顶点数,m边数,index为时间戳,cnt为强连通分量个数//dfn用来保存时间戳(次序)编号,low保存顶点i或i的子树最早的次序编号//belong用来缩点的数组,值相等的对应下标在同一个强连通分量内bool instack[MAXV];stack<int> s;inline void addEdge(const int &start, const int &finish){    adj[start] = new(Nptr++)Arc(finish, adj[start]);}inline void tarjan(const int &i){    dfn[i] = low[i] = ++index;    instack[i] = true;    s.push(i);    for (Arc *p = adj[i]; p; p = p->next)    {        if (!dfn[p->dest])        {            tarjan(p->dest);            if (low[i] > low[p->dest])                low[i] = low[p->dest];        }        else if (instack[p->dest])            if (low[i] > dfn[p->dest])                low[i] = dfn[p->dest];    }    if (dfn[i] == low[i])    {        //com[++cnt].clear();cnt++;//        int j;        do//缩点        {            j = s.top();            s.pop();            instack[j] = false;            com[cnt].push_back(j);            belong[j] = cnt;        }while (j != i);    }}int main(){    scanf("%d", &n);        memset(adj, 0, sizeof(adj));        memset(instack, false, sizeof(instack));        memset(dfn, 0, sizeof(dfn));        index = 0, Nptr = Npool, cnt = 0;        for (int i = 0; i <= n; i++)            com[i].clear();        while (!s.empty())            s.pop();        for (int i = 1; i <= n; i++)        {            int s, t;            while(scanf("%d", &s),s)            addEdge(i, s);        }        for (int i = 1; i <= n; i++)            if (!dfn[i])                tarjan(i);        bool in[MAXV]={0},out[MAXV]={0};////        int In=0,Out=0;        for(int i=1;i<=n;i++){            for (Arc *p = adj[i]; p; p = p->next)            if(belong[i]!=belong[p->dest]){                in[belong[p->dest]]=true;//不合要求,要的只是出入度为零的,其余不管                out[belong[i]]=true;            }        }        for(int i=1;i<=cnt;i++){            if(!in[i])In++;            if(!out[i])Out++;        }        cout<<In<<endl<<((cnt==1)?0:max(In,Out))<<endl;//为何min    return 0;}`

0 0