BZOJ 4562 食物链

Posted on 2016-11-04 22:52  ziliuziliu  阅读(205)  评论(0编辑  收藏  举报

我们需要拓扑一下。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#define maxv 100500
#define maxe 200500
using namespace std;
int n,m,x,y,g[maxv],nume=1,d[maxv],size[maxv],ans=0;
queue <int> q;
bool flag[maxv];
struct pnt
{
    int id,rank;
}p[maxv];
struct edge
{
    int v,nxt;
}e[maxe];
bool cmp(pnt x,pnt y){return x.rank<y.rank;}
void addedge(int u,int v)
{
    e[++nume].v=v;
    e[nume].nxt=g[u];
    g[u]=nume;
}
void topusort()
{
    for (int i=1;i<=n;i++)
    {
        if (!d[i]) 
        {
            p[i].rank=1;
            q.push(i);
        }
    }
    while (!q.empty())
    {
        int head=q.front();q.pop();
        for (int i=g[head];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (!--d[v])
            {
                p[v].rank=p[head].rank+1;
                q.push(v);
            }
        }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++)    
    {
        scanf("%d%d",&x,&y);
        addedge(x,y);d[y]++;
    }
    for (int i=1;i<=n;i++) p[i].id=i;
    topusort();
    sort(p+1,p+n+1,cmp);
    for (int i=n;i>=1;i--)
    {
        int x=p[i].id;
        for (int j=g[x];j;j=e[j].nxt)
        {
            int v=e[j].v;
            flag[x]=true;size[x]+=size[v];
        }
        if (!flag[x]) size[x]=1;
    }
    for (int i=1;i<=n;i++)
    {
        if ((p[i].rank==1) && (flag[p[i].id])) ans+=size[p[i].id];
        else if (p[i].rank!=1) break;
    }
    printf("%d\n",ans);
    return 0;
}