zoukankan      html  css  js  c++  java
  • hdu 1269 迷宫城堡

    题目连接

    http://acm.hdu.edu.cn/showproblem.php?pid=1269  

    迷宫城堡

    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

    强联通分量裸题。。

    Tarjan求强联通分量参见:https://www.byvoid.com/blog/scc-tarjan/

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 10100;
    struct Tarjan_Scc {
    	stack<int>s;
    	bool instack[N];
    	struct edge { int to, next; }G[N * 10];
    	int scc, idx, tot, dfn[N], low[N], head[N];
    	inline void init(int n) {
    		scc = tot = idx = 0;
    		while (!s.empty()) s.pop();
    		for (int i = 0; i < n + 2; i++) {
    			head[i] = -1;
    			instack[i] = false;
    			dfn[i] = low[i] = 0;
    		}
    	}
    	inline void add_edge(int u, int v) {
    		G[tot].to = v, G[tot].next = head[u], head[u] = tot++;
    	}
    	inline void built(int m) {
    		int u, v;
    		while (m--) {
    			scanf("%d %d", &u, &v);
    			add_edge(u, v);
    		}
    	}
    	inline void tarjan(int u) {
    		dfn[u] = low[u] = ++idx;
    		s.push(u);
    		instack[u] = true;
    		for (int i = head[u]; ~i; i = G[i].next) {
    			int &v = G[i].to;
    			if (!dfn[v]) {
    				tarjan(v);
    				low[u] = min(low[u], low[v]);
    			} else if (instack[v] && dfn[v] < low[u]) {
    				low[u] = dfn[v];
    			}
    		}
    		if (low[u] == dfn[u]) {
    			scc++;
    			int v = 0;
    			do {
    				v = s.top(); s.pop();
    				instack[v] = false;
    			} while (v != u);
    		}
    	}
    	inline void solve(int n, int m) {
    		init(n);
    		built(m);
    		for (int i = 1; i <= n; i++) {
    			if (!dfn[i]) tarjan(i);
    		}
    		puts(scc == 1 ? "Yes" : "No");
    	}
    }go;
    int main() {
    #ifdef LOCAL
    	freopen("in.txt", "r", stdin);
    	freopen("out.txt", "w+", stdout);
    #endif
    	int n, m;
    	while (~scanf("%d %d", &n, &m), m + n) {
    		go.solve(n, m);
    	}
    	return 0;
    }
  • 相关阅读:
    1451. Rearrange Words in a Sentence
    1450. Number of Students Doing Homework at a Given Time
    1452. People Whose List of Favorite Companies Is Not a Subset of Another List
    1447. Simplified Fractions
    1446. Consecutive Characters
    1448. Count Good Nodes in Binary Tree
    709. To Lower Case
    211. Add and Search Word
    918. Maximum Sum Circular Subarray
    lua 时间戳和时间互转
  • 原文地址:https://www.cnblogs.com/GadyPu/p/4999027.html
Copyright © 2011-2022 走看看