• 洛谷P3388 【模板】割点(割顶)


    题目链接:

    kma!

    题目分析:

    割点模板,对于当前搜索的节点是不是搜索树里的根节点分类讨论

    • 如果是根节点,显然如果它的子树数量(>=2),把它(cut)掉两棵子树就不连通了
    • 如果不是根节点,如果有搜到的节点(low[v] >= dfn[u]),说明有节点不通过(u)没办法上翻到环外,那么把它(cut)掉也是可行的
      没了

    代码:

    #include <bits/stdc++.h>
    #define N (300000 + 10)
    using namespace std;
    inline int read() {
    	int cnt = 0, f = 1; char c = getchar();
    	while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
    	while (isdigit(c)) {cnt = (cnt << 3) + (cnt << 1) + c - '0'; c = getchar();}
    	return cnt * f;
    }
    int nxt[N], first[N], to[N], tot, sign, low[N], dfn[N], cnt;
    int ans[N], son[N], flag;
    void Add(int x, int y) {nxt[++tot] = first[x], first[x] = tot, to[tot] = y;}
    void tarjan (int u, int fa) {
    	dfn[u] = low[u] = ++sign;
    	for (register int i = first[u]; i; i = nxt[i]) {
    		if (!dfn[to[i]]) {
    			tarjan(to[i], fa), low[u] = min(low[u], low[to[i]]);
    			if (u == fa) ++son[u]; 
    			if (low[to[i]] >= dfn[u] && u != fa) ans[++cnt] = u;
    		}
    		else if (dfn[to[i]] < low[u]) low[u] = min(low[u], dfn[to[i]]);
    	}
    	if (u == fa && son[u] >= 2) ans[++cnt] = u;
    }
    int n, m, x, y;
    int main() {
    //	freopen("1.in", "r", stdin);
    	n = read(), m = read();
    	for (register int i = 1; i <= m; i++) {
    		x = read(), y = read();
    		Add(x, y), Add(y, x);
    	}
    	for (register int i = 1; i <= n; i++) if (!dfn[i]) tarjan(i, i);
    	sort(ans + 1, ans + cnt + 1);
    	int q = unique (ans + 1, ans + cnt + 1) - ans - 1; 
    	printf("%d
    ", q);
    	for (register int i = 1; i <= q; i++) printf("%d ", ans[i]); 
    	return 0;
    }
    
  • 相关阅读:
    转盘抽奖活动代码
    信息滚动条
    gulp应用学习
    js实现语音播报功能
    如何安装使用sass
    纯CSS写三角形-border法
    css兼容性写法
    字体中英文对照
    浏览器内核判断
    个人课程总结
  • 原文地址:https://www.cnblogs.com/kma093/p/11331979.html
Copyright © 2020-2023  润新知