[BZOJ1051][HAOI2006]受欢迎的牛(Tarjan求强连通分量)
来源:互联网 发布:北京java培训 编辑:程序博客网 时间:2024/05/18 09:10
题目描述
传送门
题解
求出度为0的连通分量的个数,如果个数为1就输出这个强连通分量中点的个数,否则输出0。
代码
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;#define N 50005int n,m,dfs_clock,scc,ans,ansk;int x[N],y[N];int tot,point[N],nxt[N],v[N];int dfn[N],low[N],st[N],t,out[N],belong[N],cnt[N];bool vis[N];void add(int x,int y){ ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;}void tarjan(int x){ dfn[x]=low[x]=++dfs_clock;vis[x]=1;st[++t]=x; for (int i=point[x];i;i=nxt[i]) if (!dfn[v[i]]) { tarjan(v[i]); low[x]=min(low[x],low[v[i]]); } else if (vis[v[i]]) low[x]=min(low[x],dfn[v[i]]); if (dfn[x]==low[x]) { int now=0;++scc; while (now!=x) { now=st[t--]; belong[now]=scc; ++cnt[scc]; vis[now]=0; } }}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=m;++i) { scanf("%d%d",&x[i],&y[i]); add(x[i],y[i]); } for (int i=1;i<=n;++i) if (!dfn[i]) tarjan(i); for (int i=1;i<=m;++i) if (belong[x[i]]!=belong[y[i]]) ++out[belong[x[i]]]; for (int i=1;i<=scc;++i) if (!out[i]) ++ans,ansk=i; if (ans==1) printf("%d\n",cnt[ansk]); else puts("0");}
手工栈
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;#define N 50005int n,m,dfs_clock,scc,ans,ansk;int x[N],y[N];int tot,point[N],nxt[N],v[N];int dfn[N],low[N],st[N],t,out[N],belong[N],cnt[N];bool vis[N];int father[N],stack[N],cur[N];void add(int x,int y){ ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;}void tarjan(int x){ int tmp=0;t=0;stack[++tmp]=x; dfn[x]=low[x]=++dfs_clock;vis[x]=1;st[++t]=x;cur[x]=point[x]; while (tmp) { int x=stack[tmp]; if (!cur[x]) { --tmp; if (dfn[x]==low[x]) { int now=0;++scc; while (now!=x) { now=st[t--]; belong[now]=scc; ++cnt[scc]; vis[now]=0; } } if (father[x]) low[father[x]]=min(low[father[x]],low[x]); continue; } int vt=v[cur[x]]; if (!dfn[vt]) { stack[++tmp]=vt;st[++t]=vt; dfn[vt]=low[vt]=++dfs_clock; father[vt]=x;vis[vt]=1; cur[vt]=point[vt]; } else if (vis[vt]) low[x]=min(low[x],dfn[vt]); cur[x]=nxt[cur[x]]; }}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=m;++i) { scanf("%d%d",&x[i],&y[i]); add(x[i],y[i]); } for (int i=1;i<=n;++i) if (!dfn[i]) tarjan(i); for (int i=1;i<=m;++i) if (belong[x[i]]!=belong[y[i]]) ++out[belong[x[i]]]; for (int i=1;i<=scc;++i) if (!out[i]) ++ans,ansk=i; if (ans==1) printf("%d\n",cnt[ansk]); else puts("0");}
0 0
- bzoj1051 [HAOI2006]受欢迎的牛(tarjan求强连通分量)
- [BZOJ1051][HAOI2006]受欢迎的牛(Tarjan求强连通分量)
- [BZOJ1051] [HAOI2006] 受欢迎的牛 - tarjan强连通分量
- 【bzoj1051】【HAOI2006】【受欢迎的牛】【强连通分量】
- BZOJ1051 [HAOI2006]受欢迎的牛(强连通分量+缩点)
- BZOJ1051: [HAOI2006]受欢迎的牛(强连通Tarjan 缩点)
- 【题解】 [HAOI2006]受欢迎的牛(强连通分量 tarjan)
- [BZOJ1051]HAOI2006受欢迎的牛|强联通分量
- BZOJ 1051: [HAOI2006]受欢迎的牛 强连通分量,Tarjan缩点
- 【bzoj1051】 [HAOI2006]受欢迎的牛 tarjan
- 【Tarjan】BZOJ1051(HAOI2006)[受欢迎的牛]题解
- [bzoj1051][HAOI2006]受欢迎的牛 Tarjan
- 【Tarjan】BZOJ1051 [HAOI2006]受欢迎的牛
- BZOJ1051 [HAOI2006]受欢迎的牛 tarjan
- 【bzoj1051】【强连通分量】【强连通分量2006】受欢迎的牛
- bzoj1051: [HAOI2006]受欢迎的牛(强联通)
- 【BZOJ】【P1051】【HAOI2006】【受欢迎的牛】【强连通分量】
- 【bzoj1309】【HAOI2006】【受欢迎的牛】【强连通分量缩点】
- thinkphp框架中ajax向控制器传递参数数组
- 交换两个数的特殊方法
- Java反射机制解析
- 课程练习二-1017非常可乐
- 2016西电校赛网络赛 Problem D 抢人头
- [BZOJ1051][HAOI2006]受欢迎的牛(Tarjan求强连通分量)
- 数据结构与算法学习02:链表
- Android Studio常用快捷键
- Linux学习系列-IO模型
- python中input与raw_input()
- 位运算与及大小端机
- [BZOJ1901]Dynamic Rankings(动态主席树)
- ZOJ 3785 What day is that day?【思维+递推循环节】
- 矩阵卷积