迷宫城堡 【求SCC 个数】
来源:互联网 发布:网络应用安全包括 编辑:程序博客网 时间:2024/05/18 00:48
为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明可以通过这个通道由A房间到达B房间,但并不说明通过它可以由B房间到达A房间。Gardon需要请你写个程序确认一下是否任意两个房间都是相互连通的,即:对于任意的i和j,至少存在一条路径可以从房间i到房间j,也存在一条路径可以从房间j到房间i。
Input
输入包含多组数据,输入的第一行有两个数:N和M,接下来的M行每行有两个数a和b,表示了一条通道可以从A房间来到B房间。文件最后以两个0结束。
Output
对于输入的每组数据,如果任意两个房间都是相互连接的,输出”Yes”,否则输出”No”。
Sample Input
3 3
1 2
2 3
3 1
3 3
1 2
2 3
3 2
0 0
Sample Output
Yes
No
Hint
学习了,第一道 SCC
对于 SCC 的tarjan算法的学习理解,可以参考
http://www.cnblogs.com/uncle-lu/p/5876729.html
还有这个
http://m.blog.csdn.net/article/details?id=16361033
代码
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<cmath>#include<queue>#include<stack>#include<map>#include<vector>#include<set>#define CLR(a,b) memset((a),(b),sizeof(a))#define inf 0x3f3f3f3f#define mod 100009#define LL long long#define M 100000+100#define ll o<<1#define rr o<<1|1#define lson o<<1,l,mid#define rson o<<1|1,mid+1,rusing namespace std;void read(int &x){ x=0;char c; while((c=getchar())<'0'); do x=x*10+c-'0';while((c=getchar())>='0');}struct Edge { int from,to,next;}edge[M];int head[M],top; // 向前星存图 int dfs_clock;// 时间戳int sccno[M];//sccno[i] 表示 i是属于哪个 SCC ;int scc_cnt;// scc_cnt 表明有几个 SCC bool Instack[M];// 该点是不是字栈中int low[M]; // 以当前i为父节点的子树 能够连接到栈中最上面的点的 DFN 的值(能连接到的最小的dfn值) int dfn[M];//作为这个点搜索的次序编号(时间戳),就是第几个被搜索到的;(也可以说是深度) int n,m;stack<int>S; // 存储整个强联通分量 void init(){ memset(Instack,false,sizeof(Instack)); memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(sccno,0,sizeof(sccno)); memset(head,-1,sizeof(head)); top=scc_cnt=dfs_clock=0; } void addedge(int a,int b){ Edge e={a,b,head[a]}; edge[top]=e;head[a]=top++;}void getmap(){ int a,b; while(m--) { read(a);read(b); addedge(a,b); }}void tarjan(int now,int fa){ int nexts; int i,j; low[now]=dfn[now]=++dfs_clock; S.push(now); Instack[now]=true; for(i=head[now];i!=-1;i=edge[i].next) { Edge e=edge[i]; if(!dfn[e.to]) // 没有搜索到过 { tarjan(e.to,now); low[now]=min(low[now],low[e.to]); } else if(Instack[e.to]) // 已经搜索到过,并且还在 栈中, 当前点和在栈中的点有父子关系 low[now]=min(low[now],dfn[e.to]); } if(low[now]==dfn[now]) // 表明 这个节点是当前这个强联通分量的 根节点(因为这个low是这个强联通分量里最小的) { scc_cnt++; for(;;) //将 此节点 以及 比此节点后进来的 节点都出栈,出栈的所有节点 就构成了一个 全新的强联通分量 { nexts=S.top(); S.pop(); Instack[nexts]=false; if(nexts==now) break; } } }void find_cut(int l,int r) // 询问 l到r顶点 是不是在同一个SCC中 { for(int i=l;i<=r;i++) if(!dfn[i]) tarjan(i,-1); puts(scc_cnt==1?"Yes":"No"); }int main(){ while(scanf("%d%d",&n,&m)&&(n||m)) { init(); getmap(); find_cut(1,n); } return 0;}
0 0
- 迷宫城堡 【求SCC 个数】
- hdoj1269迷宫城堡【scc】
- HDU 1269 -- 迷宫城堡【有向图求SCC的数目 && 模板】
- HDU 1269 迷宫城堡 (tarjan scc)
- hdoj 1269 迷宫城堡 【有向图SCC 入门题目】
- hdu 1296 迷宫城堡【有向图scc+Tarjan入门】
- hdoj 迷宫城堡 1269 (有向图SCC) 入门题
- 迷宫城堡
- 迷宫城堡
- 迷宫城堡
- 迷宫城堡
- 迷宫城堡
- 迷宫城堡 Tarjan求出强联通分量的个数
- tajian求强连通——迷宫城堡
- HDU - 1269 - 迷宫城堡 (tarjan求强连通分量)
- [HDU1269]迷宫城堡(Tarjan求强连通分量)
- HDU 1269 迷宫城堡 简单求连通块
- hdu1269 迷宫城堡 tarjan求强联通分量
- 第1章、安装和运行Lift
- Android jdk1.8的使用配置并解决android jack编译乱码
- 融云、环信dlopen failed: library "libsqlite.so" not found
- Numpy基础 --数组和矢量计算 利用Python进行数据分析读书笔记
- QT5.2中文乱码解决问题
- 迷宫城堡 【求SCC 个数】
- (13.1.2)PMBOK之二:五大过程组及其涉及的输入、输出、工具技术
- web.py的ctx(context)
- 文章标题
- 300.leetcode-Longest Incresing Subsequence最长递增子序列
- IT项目经理应该做什么
- 指针数组和二级指针的排序应用实例
- AngularJS快速入门5--过滤器
- 汇编