强联通分量 缩点 tarjan算法
来源:互联网 发布:百度验证码算法 编辑:程序博客网 时间:2024/05/16 07:53
/*做一遍DFS,用dfn[i]表示编号为i的节点在DFS过程中的访问序号(也可以叫做开始时间)用low[i]表示i节点DFS过程中i的下方节点所能到达的开始时间最早的节点的开始时间。初始时dfn[i]=low[i]在DFS过程中会形成一搜索树。在搜索树上越先遍历到的节点,显然dfn的值就越小。DFS过程中,碰到哪个节点,就将哪个节点入栈。栈中节点只有在其所属的强连通分量已经全部求出时,才会出栈。如果发现某节点u有边连到搜索树中栈里的节点v,则更新u的low 值为dfn[v](更新为low[v]也可以)。如果一个节点u已经DFS访问结束,而且此时其low值等于dfn值,则说明u可达的所有节点,都不能到达任何在u之前被DFS访问的节点 ---- 那么该节点u就是一个强连通分量在DFS搜索树中的根。此时将栈中所有节点弹出,包括u,就找到了一个强连通分量*//*本体题意: *有N(N<=10000)头牛,每头牛都想成为most poluler的牛; *给出M(M<=50000)个关系,如(1,2)代表1欢迎2,关系可以传递,但是不可以相互,即1欢迎2不代表2欢迎1; *但是如果2也欢迎3那么1也欢迎3; *给出N,M和M个欢迎关系,求被所有牛都欢迎的牛的数量; *求出强联通分量后,所以解题的方法就应该是在缩点之后的图G中求出所有出度为零的点的个数,如果个数大于1, 说明至少存在两个分量之间的牛不会相互YM,明显和题目要求不符合,输出0,如果等于1则说明只有一个强连通分 量里面的牛被其他全部的牛YM,那么答案就是这个分量中点的个数 */#include <cstdio>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#define N 50010using namespace std;int dfs[N],instack[N],low[N],out[N],belong[N];int stack[N];int deep,top,cnt,n,m;vector<int> map[N];int min(int a,int b){ return a>b?b:a;}void tarjan(int k){ int i,j; dfs[k]=low[k]=++deep; stack[++top]=k; instack[k]=1; for(i=0; i<map[k].size(); i++) { j=map[k][i]; if(dfs[j]==0) { tarjan(j); low[k]=min(low[k],low[j]); } else if(instack[j]) { low[k]=min(low[k],dfs[j]); } } if(low[k]==dfs[k]) { cnt++; do { j=stack[top--]; belong[j]=cnt; instack[j]=0; } while(j!=k); }}int main(){ int i,j,a,b,ans,num,pos; while(scanf("%d%d",&n,&m)!=EOF) { memset(dfs,0,sizeof(dfs)); memset(instack,0,sizeof(instack)); memset(low,0,sizeof(low)); memset(out,0,sizeof(out)); memset(belong,0,sizeof(belong)); memset(stack,0,sizeof(stack)); memset(map,0,sizeof(map)); deep=top=cnt=0; for(i=1; i<=m; i++) { scanf("%d%d",&a,&b); map[a].push_back(b); } for(i=1; i<=n; i++) if(dfs[i]==0) tarjan(i); if(cnt==1) { printf("%d\n",n); continue; } for(i=1; i<=n; i++) for(j=0; j<map[i].size(); j++) if(belong[i]!=belong[map[i][j]]) { out[belong[i]]++; } ans=pos=num=0; for(i=1; i<=cnt; i++) if(!out[i]) { num++; pos=i; } if(num==1) { for(j=1; j<=n; j++) if(belong[j]==pos) { ans++; } printf("%d\n",ans); } else printf("0\n"); } return 0;}
0 0
- 强联通分量 缩点 tarjan算法
- Tarjan算法---强联通分量
- 强联通分量 Tarjan算法
- BZOJ 2438 杀人游戏 强联通分量tarjan缩点
- 强联通分量 缩点 tarjan 入门题小集
- POJ 2186 Popular Cows(强联通分量缩点+tarjan算法)
- 强联通分量 Tarjan算法 模板
- 求解强联通分量 tarjan算法
- 强联通分量模板---基于tarjan算法
- 强联通分量的tarjan算法
- 强联通分量-tarjan
- 强联通分量+缩点
- hdu1269 tarjan强联通分量
- tarjan求强联通分量
- tarjan求强联通分量
- “tarjan陪伴强联通分量
- 强连通分量及缩点tarjan算法解析
- 强连通分量及缩点tarjan算法解析
- Winpcap捕获数据包并转发
- OC 的冒泡排序问题
- pentesterlab学习记录-week2
- 使用STL实现LRU缓存
- cocos2d-x游戏开发 跑酷(七) 添加金币和岩石
- 强联通分量 缩点 tarjan算法
- 黑马程序员--基础加强(JDK1.5新特性)
- typedef
- 【iOS】ArcGIS for iOS环境配置
- HashMap相关推荐
- 百度编辑器向数据库提交数据后字符转义的问题
- 手形看你一生的命运
- Android Settings剖析与修改
- Linux 和 Windows 网络命令汇总