bzoj 1051简单tarjan

来源:互联网 发布:大数据与经济发展 编辑:程序博客网 时间:2024/05/30 02:24

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1051
简单缩点后,判断出度为0的一个强连通分量,答案加上分量里点的个数就可。

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;struct Edge{    int v,next;};Edge e[50005];int n,m,a,b,num,head[10005],ans=0;int idc,dfn[10005],low[10005],scc,belong[10005],ins[10005],st[10005],top,out[10005],cnt[10005];void adde(int i,int j){    e[++num].v=j;    e[num].next=head[i];    head[i]=num;}void tarjan(int u){    dfn[u]=low[u]=++idc;    ins[u]=1;st[++top]=u;    for(int i=head[u];i;i=e[i].next){        int v=e[i].v;        if(!dfn[v]){            tarjan(v);            low[u]=min(low[u],low[v]);        }        else if(ins[v])low[u]=min(low[u],dfn[v]);    }    if(dfn[u]==low[u]){        int now=-1;scc++;        while(now!=u){            now=st[top--];            ins[now]=0;            belong[now]=scc;            cnt[scc]++;        }    }}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++){        scanf("%d%d",&a,&b);        adde(a,b);    }    for(int i=1;i<=n;i++)    if(!dfn[i])tarjan(i);    for(int u=1;u<=n;u++)    for(int i=head[u];i;i=e[i].next)    if(belong[e[i].v]!=belong[u])out[belong[u]]++;    for(int i=1;i<=scc;i++)    if(out[i]==0)ans+=cnt[i];    printf("%d\n",ans);    return 0;}
原创粉丝点击