首页 > 其他分享 >【图论】割点与桥

【图论】割点与桥

时间:2023-06-17 13:22:53浏览次数:32  
标签:tarjan int 图论 割点 dfn low include

目录

定义

割点

如果删除无向图中的某个点会使无向图的连通分量数增多,则把这个点称为割点。

割边(桥)

如果删除无向图中的某条边会使无向图的连通分量数增多,则把这个点称为割边(桥)。

关系

桥的两端可以有割点。

算法

求割点

割点:存在子树最高只能到达这个点自己

dfn[x]:x的dfs序
low[x]不经过父节点,x能到达的最小序号
low[x] = min(dfn[x], low[y]);
如果x的某个儿子有:
dfn[x] <= low[y],那么x是割点
根节点要特判:根节点儿子数>1才是割点

伪代码

void tarjan(int x)
{
    dfn[x] = low[x] = ++clk;
    bool cut = false;
    枚举邻居y:
        if(!dfn[y])
        {
            tarjan(y);
            low[x] = min(low[x],low[y]);
            if(dfn[x] <= low[y]) cut = true;
        }
        else low[x] = min(low[x],dfn[y]);
    if(x是根节点&&儿子数<=1) cut = false;
    if(cut) ans++;
}

for(i -> n)
    if(dfn[i] == 0)
        tarjan(i);

模版

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;

int n, dfn[110], low[110], ans, clk;
vector<int> g[110];

void tarjan(int x)
{
    dfn[x] = low[x] = ++clk;
    bool cut = false;
    int child = 0;
    for(int i = 0;i < g[x].size();i++)
    {
    	int y = g[x][i];
        if(!dfn[y])
        {
            tarjan(y);child++;
            low[x] = min(low[x],low[y]);
            if(dfn[x] <= low[y]) cut = true;
        }
        else low[x] = min(low[x],dfn[y]);
    }
    if(x==1 && child<2) cut = false;
    if(cut) ans++;
}
int main()
{
    while(1)
    {
        scanf("%d",&n);if(n==0) break;
        for(int i = 1;i <= n;i++) g[i].clear();
        memset(dfn, 0, sizeof(dfn));memset(low, 0, sizeof(low));ans = clk = 0;
        while(1)
        {
            int x;
            scanf("%d", &x);
            if(x == 0) break;
            while(1)
            {
                int y;char c;
                scanf("%d%c", &y, &c);
                g[x].push_back(y);
                g[y].push_back(x);
                if(c == '\n') break;
            }
        }

        tarjan(1);
        printf("%d\n", ans);
    }
    return 0;
}

标签:tarjan,int,图论,割点,dfn,low,include
From: https://www.cnblogs.com/ghivan911/p/17487377.html

相关文章

  • POJ2117 Electricity 题解 tarjan点双连通分量 割点
    题目链接:http://poj.org/problem?id=2117题目大意:给定一个由\(n\)个点\(m\)解题思路:tarjan,判断\(u\)的子节点有几个\(v\)满足\(low[v]\gedfn[u]\)就是答案,但是同时如果\(u\)不是这个dfs树的根节点,个数还要加\(1\)。示例程序1(C++11,POJ不支持):#include<bits/stdc++.h>......
  • POJ2117 Electricity 题解 tarjan点双连通分量 割点
    题目链接:http://poj.org/problem?id=2117题目大意:给定一个由\(n\)个点\(m\)条边构成的无向图,请你求出该图删除一个点之后,连通块最多有多少。解题思路:tarjan,判断\(u\)的子节点有几个\(v\)满足\(low[v]\gedfn[u]\)就是答案,但是同时如果\(u\)不是这个dfs树的根节......
  • 【P8819 [CSP-S 2022]】 星战 题解(图论 + 哈希)
    图论+哈希。Link.因为实在是太妙了所以写个题解。Solution因为每个点的出度都为\(1\),所以从任意一点出发永远可以走下去,故每次只需判断每个点度数是否为\(1\)即可。然后一三操作显然直接\(O(1)\)维护,\(50\pts\)。考虑二四操作。每次操作显然对点\(u\)的出度......
  • [Week 20]每日一题(C++,图论,数学,搜索)
    目录T1[Daimayuan]Collision(C++,多源最短路)题目描述输入描述输出描述样例输入1样例输出1样例输入2样例输处2数据范围解题思路T2[Daimayuan]农田划分(C++,数学,BFS)题目描述题目输入题目输出样例输入1样例输出1样例输入2样例输出2数据范围解题思路T3[Daimayuan]三段式(C++,数组前缀......
  • 离散数学(屈婉玲)第二版 第五部分 图论 总结
    第5部分  图论前言:图是我们日常生活中一个很常见的概念,我们学习时会画思维导图,思维导图有节点,有路线;生活中会用到地图导航,有起点有终点有路线。而图论中的图便是生活中以及数学中具象事物抽象化的体现。前言的前言:若有错误之处或不完整之处希望指出,虚心接受任何批评和建议!一.......
  • 3. 搜索与图论(I)
    3.1DFS(深度优先搜索)例题:AcWing842.排列数字题目:给你一个数\(n\),按字典序将长度为\(n\)的全排列全部输出。\(1\len\le9\)。思路:运用DFS暴力搜索即可,时间复杂度\(O(n!)\)。图3-1(图源:AcWing@Hasity)如图\(\texttt{3-1}\)展示了\(n=3\)时的搜索过程:初始时......
  • leetcode-图论总结
    此文总结一下常见图论算法,代码可以为后续遇见类似题目提供参考:1.图的表示:邻接矩阵:可通过创建数组得到邻接表:我个人喜欢通过LinkedList<int[]>[]graph=newLinkedList[n];得到。EdgeList:同样可以通过LinkedList<int[]>[]graph=newLinkedList[n];得到。2.图遍历:DF......
  • 离散数学图论部分总结
    图论内容总结前言:图论这一部分内容可谓离散数学的点睛之笔,离散数学很多堆砌的概念在这章似乎都活过来了(可能是因为我刷算法题的原因),概念之间的联系更加的紧密。学完图论部分我感觉里面很多的知识点都非常重要,比如顶点度数,握手定理,树,而考点的话除了这些,还有求欧拉回路,最短路径问......
  • 蓝桥杯----图论训练
    STL当想要维护一个数组,其中的元素要求有序,同时可能随时对这个数组中的元素进行增减有没有一个STL可以快速维护一个这样的数组?multiset(平衡二叉树) 默认从小到大排序注意离散化中清除重复元素的原理:unique()函数     vector......
  • 图论
    ///朴素dijkstra算法——模板题AcWing849.Dijkstra求最短路I///时间复杂是O(n2+m)O(n2+m),nn表示点数,mm表示边数#include<bits/stdc++.h>usingnamespacestd;constintN=510;intn,m;intg[N][N];//存储每条边intdist[N];//存储1号点到每个点的最短距......