• 洛谷 [P3388] 割点模版


    tarjan 求无向图的割点

    割点,即割去此点后原图可变为两个或多个独立的联通块
    一个点 x 是割点,当且仅当存在一个x 的子节点 y ,使得 low[y] >= dfn[x]
    对于根节点来说,需要两个满足的节点

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    const int MAXN = 100005;
    int head[MAXN], nume, rot, n, m, dfn[MAXN], low[MAXN], ind, cnt;
    bool f[MAXN];
    struct edge{
    	int to, nxt;
    }e[MAXN << 1];
    void adde(int from, int to) {
    	e[++nume].to = to;
    	e[nume].nxt = head[from];
    	head[from] = nume;
    }
    int init() {
    	int rv = 0, fh = 1;
    	char c = getchar();
    	while(c < '0' || c > '9') {
    		if(c == '-') fh = -1;
    		c = getchar();
    	}
    	while(c >= '0' && c <= '9') {
    		rv = (rv<<1) + (rv<<3) + c - '0';
    		c = getchar();
    	}
    	return fh * rv;
    }
    void tarjan(int u) {
    	dfn[u] = low[u] = ++ind;
    	int flag = 0;
    	for(int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].to;
    		if(!dfn[v]) {
    			tarjan(v);
    			low[u] = min(low[u], low[v]);
    			if(low[v] >= dfn[u]) {
    				flag++;
    				if(u != rot || flag > 1) f[u] = 1;
    			}
    		}else low[u] = min(low[u], dfn[v]);
    	}
    }
    int main() {
    	n = init(); m = init();
    	for(int i = 1; i <= m; i++) {
    		int u = init(), v = init();
    		adde(u, v); adde(v, u);
    	}
    	for(int i = 1; i <= n; i++) if(!dfn[i]) rot = i, tarjan(i);
    	for(int i = 1; i <= n; i++) if(f[i]) cnt++;
    	cout << cnt << endl;
    	for(int i = 1; i <= n; i++) if(f[i]) printf("%d ", i);
    	printf("
    ");
    	return 0;
    }
    
  • 相关阅读:
    网络安全分析
    java实现 洛谷 P1464 Function
    java实现 洛谷 P1464 Function
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1540 机器
    java实现 洛谷 P1540 机器
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8690964.html
Copyright © 2020-2023  润新知