BZOJ 4562: [Haoi2016]食物链【拓扑】

4562: [Haoi2016]食物链

【题目描述】
传送门

【题解】

简单的拓扑,但是单点不算食物链。

代码如下

#include<cstdio>
#include<cctype>
#include<queue>
#define MAXN 100005
#define MAXE 200005
using namespace std;
int n,m,r[MAXN],c[MAXN];
long long f[MAXN],Ans;
bool vis[MAXN];
queue<int> que;
struct Edge{
    int tot,lnk[MAXN],son[MAXE],nxt[MAXE];
    void Add(int x,int y){son[++tot]=y;nxt[tot]=lnk[x];lnk[x]=tot;r[y]++,c[x]++;}
}E;
int read(){
    int ret=0;char ch=getchar();bool f=1;
    for(;!isdigit(ch);ch=getchar()) f^=!(ch^'-');
    for(; isdigit(ch);ch=getchar()) ret=(ret<<3)+(ret<<1)+ch-48;
    return f?ret:-ret;
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=m;i++){
        int x=read(),y=read();E.Add(x,y);
    }
    for(int i=1;i<=n;i++)
    if(!r[i]) f[i]=1,que.push(i);
    while(!que.empty()){
        int x=que.front();que.pop();
        for(int j=E.lnk[x];j;j=E.nxt[j]){
            f[E.son[j]]+=f[x],r[E.son[j]]--;vis[E.son[j]]=1;
            if(!r[E.son[j]]) que.push(E.son[j]);
        }
    }
    for(int i=1;i<=n;i++) if(c[i]==0&&vis[i]) Ans+=f[i];
    printf("%lld\n",Ans);
    return 0;
}
posted @ 2018-07-06 13:29  XSamsara  阅读(85)  评论(0编辑  收藏  举报