连通图 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit Status
Description
为了训练小希的方向感,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
只要任意两点直接或间接连接,就是说这个图是一个强连通图;
#include<iostream> #include<vector> #include<cstring> #include<algorithm> #include<cstdio> #include<stack> #include<cmath> using namespace std; #define N 10008 int n, m, cnt, num, top, Time; // Time用来计量时间,top用来控制stackk数组的下标 int dfn[N], low[N], stackk[N]; // dfn数组存到达下标的最小时间,low存下标可以走到的最小的点,stackk是自己建的栈,用来存深搜先后进入的点 bool instack[N]; // 判断是否进栈 vector<vector<int> > G; void init() // 初始化 { G.clear(); G.resize(n+1); memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); memset(stackk, 0, sizeof(stackk)); memset(instack, false, sizeof(instack)); cnt = num = top = Time = 0; } void Tarjan(int u) // 从1点开始进栈,进栈一次Time更新 { low[u] = dfn[u] = ++Time; stackk[top++] = u; instack[u] = true; // 已经进栈就标记true int len = G[u].size(), v; for(int i = 0; i < len; i++) { v = G[u][i]; // 与进栈的点所连接的点 if(!dfn[v]) // 如果这个点还没有被访问过,就把这个点遍历,low随之更新,是原先值和连接的这个值的low的最小值,因为low是指下标所能到的最小的点 { Tarjan(v); low[u] = min(low[u], low[v]); } else if(instack[v]) // 如果已经进栈,就直接判断low的取值就行了, low[u] = min(low[u], dfn[v]); } if(low[u] == dfn[u]) // 如果两个点的第一次到的时间值dfn和可以到的最小值dfn一样,说明不能再往下走了,这个连通图结束,开始出栈 { do { num++; // 出栈一个数num++,计量出栈总数 v = stackk[--top]; // v用来存出栈的数,top--, instack[v] = false; // 出栈置为false,虽然对本题没多大用 }while(u != v); // 当出栈是u时,出栈结束 cnt++; // 每 一次出栈,即每一个连通图,cnt++, } } void slove() { Tarjan(1); if(cnt == 1 && num == n) // 如果cnt等于1,就是就一个连通图。而且连通图内的总数是n,即把每个数都连接在内了,那么久是一个连通图,满足题意 puts("Yes"); else puts("No"); } int main() { while(scanf("%d%d", &n, &m), n+m) { int a, b; init(); while(m--) { scanf("%d%d", &a, &b); G[a].push_back(b); // } slove(); } return 0; }
时间: 2024-10-17 05:11:32