首页 > 代码库 > 【BZOJ1051】受欢迎的牛
【BZOJ1051】受欢迎的牛
强连通分量:
首先tarjan缩点重构图
之后,若出度为0的点仅有一个,那么答案即为该点代表的强连通分量中点的个数
否则,答案为0
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int N=10010,M=50010; 5 const int novis=-1,over=1,nowvis=0; 6 int size,head[M],next[M],to[M]; 7 int head2[M],next2[M],to2[M]; 8 int low[N],dfn[N],flag[N],color[N],que[N],sum[N], 9 top,cnt,n,m,sig;10 void tarjan(),uni(int,int),dfs(int),rebuild();11 int find(),min(int,int);12 int main(){13 int ans,x,y;14 size=0;15 memset(head,0,sizeof(head));16 memset(head2,0,sizeof(head2));17 scanf("%d %d",&n,&m);18 for (int i=1;i<=m;i++){19 scanf("%d %d",&x,&y);20 uni(x,y);21 }22 tarjan();23 rebuild();24 ans=find();25 printf("%d",ans);26 return 0;27 }28 void uni(int x,int y){29 size++;30 next[size]=head[x];31 head[x]=size;32 to[size]=y;33 }34 void tarjan(){35 memset(flag,novis,sizeof(flag));36 memset(color,0,sizeof(color));37 memset(sum,0,sizeof(sum));38 sig=cnt=top=0;39 for (int i=1;i<=n;i++)40 if (flag[i]==novis) dfs(i);41 }42 void dfs(int x){43 que[++top]=x;44 flag[x]=nowvis;45 low[x]=dfn[x]=++sig;46 for (int e=head[x];e;e=next[e]){47 int v=to[e];48 if (flag[v]==novis){49 dfs(v);50 low[x]=min(low[x],low[v]);51 }52 else if (flag[v]==nowvis)53 low[x]=min(low[x],dfn[v]);54 }55 if (low[x]==dfn[x]){56 int t;cnt++;57 do{58 t=que[top--];59 color[t]=cnt;60 flag[t]=over;61 sum[cnt]++;62 }while (t!=x);63 }64 }65 void rebuild(){66 size=0;67 for (int u=1;u<=n;u++){68 for (int e=head[u];e;e=next[e]){69 int v=to[e];70 if (color[u]!=color[v]){71 size++;72 next2[size]=head2[color[u]];73 head2[color[u]]=size;74 to2[size]=color[v];75 }76 }77 }78 }79 int find(){80 int ans=0;81 for (int i=1;i<=cnt;i++)82 if (!head2[i]){83 if (ans) return 0;84 else ans=sum[i];85 }86 return ans;87 }88 int min(int x,int y){89 return x<y?x:y;90 }
【BZOJ1051】受欢迎的牛
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。