[bzoj1051][HAOI2006]受欢迎的牛【tarjan】

【题目链接】
  http://www.lydsy.com/JudgeOnline/problem.php?id=1051
【题解】
  tarjan缩点,如果只有一个块出度为0,那么那个块的所有点就是答案,否则无解
  

/* --------------
    user Vanisher
    problem bzoj-1051 
----------------*/
# include <bits/stdc++.h>
# define    ll      long long
# define    N       100100
using namespace std;
int read(){
    int tmp=0, fh=1; char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
    while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
    return tmp*fh;
}
struct node{
    int data,next;
}e[N];
int use[N],low[N],dfn[N],st[N],place,ti,head[N],size[N],p[N],top,num,n,m,tag[N],u[N],v[N];
void build(int u, int v){
    e[++place].data=v; e[place].next=head[u]; head[u]=place;
}
void tarjan(int x){
    use[x]=1; low[x]=dfn[x]=++ti; st[++top]=x;
    for (int ed=head[x]; ed!=0; ed=e[ed].next){
        if (use[e[ed].data]==0){
            tarjan(e[ed].data);
            low[x]=min(low[x],low[e[ed].data]);
        }
        if (use[e[ed].data]==1)
            low[x]=min(low[x],dfn[e[ed].data]);
    }
    if (low[x]==dfn[x]){
        num++;
        while (st[top]!=x){
            size[num]++;
            p[st[top]]=num;
            use[st[top--]]=2;
        }
        p[st[top]]=num; use[st[top--]]=2; 
        size[num]++;
    }
}
int main(){
    n=read(), m=read();
    for (int i=1; i<=m; i++){
        u[i]=read(), v[i]=read();
        build(u[i],v[i]);
    }
    for (int i=1; i<=n; i++)
        if (use[i]==0) tarjan(i);
    int cnt=0, id; 
    for (int i=1; i<=m; i++)
        if (p[u[i]]!=p[v[i]])
            tag[p[u[i]]]++;
    for (int i=1; i<=num; i++)
        if (tag[i]==0) cnt++, id=i;
    if (cnt!=1) 
        printf("0\n");
        else printf("%d\n",size[id]);
    return 0;
}
posted @ 2018-03-03 21:50  Vanisher  阅读(74)  评论(0编辑  收藏  举报