bzoj1051: [HAOI2006]受欢迎的牛

来源:互联网 发布:苹果5s数据 编辑:程序博客网 时间:2024/06/07 17:53

链接

  http://www.lydsy.com/JudgeOnline/problem.php?id=1051

题解

  缩点之后的DAG上,如果某个SCC是唯一出度为0的SCC,这个SCC的大小就是答案。否则答案为0。

代码

//强连通分量#include <cstdio>#include <algorithm>#define maxn 600000using namespace std;int vis[maxn], to[maxn], nex[maxn], head[maxn], tot, tid[maxn], dfn[maxn], low[maxn],    s[maxn], tim, cd[maxn], u[maxn], v[maxn], sz[maxn], N, M;void adde(int a, int b){to[++tot]=b;nex[tot]=head[a];head[a]=tot;}void tarjan(int pos){    int p;    vis[pos]=1;    s[++(*s)]=pos;    dfn[pos]=low[pos]=++tim;    for(p=head[pos];p;p=nex[p])    {        if(!vis[to[p]])tarjan(to[p]);        if(vis[to[p]]==1)low[pos]=min(low[pos],low[to[p]]);    }    if(dfn[pos]==low[pos])        for((*tid)++;s[*s+1]!=pos;(*s)--)tid[s[*s]]=*tid,vis[s[*s]]=2;}void init(){    int i;    scanf("%d%d",&N,&M);    for(i=1;i<=M;i++)    {        scanf("%d%d",u+i,v+i);        adde(u[i],v[i]);    }    *tid=N;    for(i=1;i<=N;i++)if(!vis[i])tarjan(i);    for(i=1;i<=tot;i++)if(tid[v[i]]^tid[u[i]])cd[tid[u[i]]]++;}int dfs(int pos){    int p, cnt=1;    vis[pos]=1;    for(p=head[pos];p;p=nex[p])if(!vis[to[p]])cnt+=dfs(to[p]);    return cnt;}void work(){    int ans=-1, i, pos;    for(i=N+1;i<=*tid;i++)        if(cd[i]==0)            if(ans==-1)ans=i;else{putchar(48);return;}    for(i=1;i<=N;i++)if(tid[i]==ans){pos=i;break;}    for(i=1,ans=0;i<=N;i++)if(tid[i]==tid[pos])ans++;    printf("%d",ans);}int main(){    init();    work();    return 0;}
0 0
原创粉丝点击