csp2020

include<cstdio>
 
#define reg register
#define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
#define erep(i,G,x) for(int i=(G).Head[x];i;i=(G).Nxt[i])
 
char buf[200000],*p1=buf,*p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,200000,stdin),p1==p2)?EOF:*p1++)
 
inline void Rd(int &res) {
    res=0;
    int flag=0;
    char c;
    while(c=getchar(),c<48||c>57)flag|=c=='-';
    do res=(res<<1)+(res<<3)+(c^48);
    while(c=getchar(),c<=57&&c>=48);
    res=flag?-res:res;
}
 
template<class T>inline bool Max(T &a,T b) {
    return a<b?a=b,1:0;
}
template<class T>inline bool Min(T &a,T b) {
    return a>b?a=b,1:0;
}
 
const int N=1e4+5,M=5e4+5;
 
bool MOP1;
 
struct Link_list {
    int Tot,Head[N],to[M],Nxt[M];
    inline void AddEdge(int a,int b) {
        to[++Tot]=b,Nxt[Tot]=Head[a],Head[a]=Tot;
    }
} G;
 
int a,b,dfn[N],low[N],stk[N],belong[N],Sz[N],Id,cnt,top;
 
bool Instack[N];
 
void dfs(int x) {
    dfn[x]=low[x]=++cnt;
    stk[++top]=x,Instack[x]=1;
    erep(i,G,x) {
        int y=G.to[i];
        if(!dfn[y])dfs(y),Min(low[x],low[y]);
        else if(Instack[y])Min(low[x],dfn[y]);
    }
    if(dfn[x]==low[x]) {
        Id++;
        int y;
        do y=stk[top--],Sz[belong[y]=Id]++,Instack[y]=0;
        while(y^x);
    }
}
 
bool MOP2;
 
inline void _main(void) {
//  cerr<<"M="<<(&MOP2-&MOP1)/1024.0/1024.0<<endl;
    int n,m;
    Rd(n),Rd(m);
    rep(i,1,m)Rd(a),Rd(b),G.AddEdge(a,b);
    rep(i,1,n)if(!dfn[i])dfs(i);
    rep(i,1,n)stk[i]=0;
    rep(i,1,n)erep(j,G,i)(belong[G.to[j]]^belong[i])&&(stk[belong[i]]=1);
    int Ans=0;
    rep(i,1,Id)if(!stk[i]) {
        if(Ans)return (void)puts("0");
        Ans=Sz[i];
    }
    printf("%d\n",Ans);
}
 
int main() {
//  freopen(".in","r",stdin),freopen(".out","w",stdout);
    _main();
//  fclose(stdin),fclose(stdout);
}
posted @ 2020-11-05 20:45  dsjkafdsaf  阅读(78)  评论(1编辑  收藏  举报