zoukankan      html  css  js  c++  java
  • 洛谷 [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;
    }
    
  • 相关阅读:
    水晶报表的部署
    成熟是一种明亮而不刺眼的光辉...
    获取页面地址的各种返回值
    索引的基本原理(转)
    cron
    VS2010 测试 普通单元测试
    SQL 学习笔记
    负载均衡
    Expression 常用方法
    轻松实现QQ用户接入
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8690964.html
Copyright © 2011-2022 走看看