zoukankan      html  css  js  c++  java
  • [洛谷P3388]【模板】割点(割顶)

    题目大意:求出一个无向图的割点

    题解:$tarjan$,若一个点为根节点(起始节点),只需要判断它有多少个儿子,若不是根节点,假如$low_vgeqslant DFN_v$就说明$v$没有返祖边,即该节点$u$为割点。

    卡点:1.多输出了一些数

      2.没有去重



    C++ Code:

    #include <cstdio>
    #include <algorithm>
    #define maxn 100010
    using namespace std;
    int n, m;
    int ans[maxn], ansnum;
    
    int head[maxn], cnt;
    struct Edge {
    	int to, nxt;
    } e[maxn << 1];
    void add(int a, int b) {
    	e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
    }
    
    int DFN[maxn], low[maxn], idx;
    inline int min(int a, int b) {return a < b ? a : b;}
    void tarjan(int u, int rt) {
    	DFN[u] = low[u] = ++idx;
    	int child = 0;
    	for (int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].to;
    		if (DFN[v]) low[u] = min(low[u], DFN[v]);
    		else {
    			tarjan(v, rt);
    			low[u] = min(low[u], low[v]);
    			if (u == rt) child++;
    			if (u != rt && low[v] >= DFN[u]) {
    				ans[ansnum++] = u;
    			}
    		}
    	}
    	if (child >= 2) ans[ansnum++] = u;
    }
    
    int main() {
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= m; i++) {
    		int a, b;
    		scanf("%d%d", &a, &b);
    		add(a, b);
    		add(b, a);
    	}
    	for (int i = 1; i <= n; i++) {
    		if (!DFN[i]) tarjan(i, i);
    	}
    	sort(ans, ans + ansnum);
    	ansnum = unique(ans, ans + ansnum) - ans;
    	printf("%d
    ", ansnum);
    	for (int i = 0; i < ansnum - 1; i++) printf("%d ", ans[i]);
    	if (ansnum) printf("%d
    ", ans[ansnum - 1]);
    	return 0;
    }
    
  • 相关阅读:
    「WC2021」表达式求值
    [补]「WC2021」括号路径
    「CEOI2020」星际迷航
    「CEOI2018」斐波那契表示法
    CF913F
    CF1017G The Tree
    NOI2020 超现实树
    LOJ 6714 Stupid Product
    LOJ 575. 不等关系
    CF1267G
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9525310.html
Copyright © 2011-2022 走看看