无向图的双联通分量

点双和边双的区别我在上一篇文章中已经讨论过了,这篇文章讲边双的求法。

由于是边双,就决定了边双中一定不含有桥,但是可以含有割顶。

所以我们对边双唯一的限制条件就是不经过桥。

如此一来,我们可以分成两次dfs,第一次求出所有的桥,第二次dfs时遍历整张图,只要保证不经过桥就可以了。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>

using namespace std;

const int maxn = 105, maxm = maxn * 2;

int n, m, tot, dfs_clock, bcc_cnt;

int h[maxn], dfn[maxn], low[maxn], iscut[maxn], vis[maxn];

struct edge
{
    int v, next, isbridge;
}a[maxm];

vector<int> bcc[maxn];

void add(int x, int y)
{
    a[tot].v = y;
    a[tot].next = h[x];
    h[x] = tot++;
}

int dfs(int u, int fa)
{
    int lowu = dfn[u] = ++dfs_clock;
    int child = 0;
    for (int i = h[u]; ~i; i = a[i].next)
    {
        int v = a[i].v;
        if (!dfn[v])
        {
            child++;
            int lowv = dfs(v, u);
            lowu = min(lowu, lowv);
            if (lowv >= dfn[u])
            {
                iscut[u] = 1;
            }
            if (lowv > dfn[u])
            {
//                printf("%d - %d\n", u, v);
                a[i].isbridge = 1;
                a[i^1].isbridge = 1;
            }
        }else if (dfn[v] < dfn[u] && v != fa)
        {
            lowu = min(lowu, dfn[v]);
        }
    }
    if (fa == 0 && child == 1)
    {
        iscut[u] = 0;
    }
    low[u] = lowu;
    return lowu;
}

void dfs2(int u, int fa)
{
    bcc[bcc_cnt].push_back(u);
    vis[u] = 1;
    for (int i = h[u]; ~i; i = a[i].next)
    {
        int v = a[i].v;
        if (v == fa || a[i].isbridge ||vis[v]) continue;
        dfs2(v, u);
    }
}

int main()
{
    freopen("无向图双联通分量.in","r",stdin);
    scanf("%d%d", &n, &m);
    memset(h, -1, sizeof h); tot = dfs_clock = 0;
    for (int i = 1; i <= m; i++)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        add(x, y); add(y, x);
    }
    dfs(1, 0);
    for (int i = 1; i <= n; i++)
        if (!vis[i])
        {
            bcc_cnt++;
            bcc[bcc_cnt].clear();
            dfs2(i, 0);
        }
    for (int i = 1; i <= bcc_cnt; i++)
    {
        for (int j = 0; j < bcc[i].size(); j++)
            printf("%d ", bcc[i][j]);
        printf("\n");
    }
    return 0;
}
时间: 2024-10-11 11:23:36

无向图的双联通分量的相关文章

POJ 1515 双联通分量

点击打开链接 题意:给一个联通的无向图,然后问你将其中的边变为有向的,加边使其变成有向的联通图 思路:若无向图有双联通分量,那么这个分量里的元素可以变成有向图的强联通,这应该很好看出来,然后需要加的边是什么呢,就是这个图上的桥呗,是桥的话变成有向的就要加一条边,然后剩下的无向图的双联通分量可以用dfs搜一下,边搜边输出就可以了,将桥记录下来遇到桥的时候特殊处理一下,然后双联通分量里的边每一条只能走一次,将走得边和反向边标记一下就行了  PS:vector写这样反向边的真是麻烦 #include

hihocoder #1190 : 连通性&#183;四 点双联通分量

http://hihocoder.com/problemset/problem/1190?sid=1051696 先抄袭一下 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho从约翰家回到学校时,网络所的老师又找到了小Hi和小Ho. 老师告诉小Hi和小Ho:之前的分组出了点问题,当服务器(上次是连接)发生宕机的时候,在同一组的服务器有可能连接不上,所以他们希望重新进行一次分组.这一次老师希望对连接进行分组,并把一个组内的所有连接关联的服务器也视为这个组内

[HDOJ4738]Caocao&#39;s Bridges(双联通分量,割边,tarjan)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4738 给一张无向图,每一条边都有权值.找一条割边,使得删掉这条边双连通分量数量增加,求权值最小那条. 注意有重边,ACEveryDay里群巨给的意见是tarjan的时候记录当前点是从哪条边来的. 注意假如桥的权值是0的时候也得有一个人去炸…… 1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6 ┛┗┛┗┛┃ノ) 7

UVA - 10765 Doves and bombs (双联通分量)

链接 :  http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34798 给N个点的无向图并且联通,问删除每次一个点之后还剩多少联通分量. 找割顶 如果删除的是割顶 联通分量就会增加,否则还是1(因为原图是联通图),删除割顶之后 联通块的数目 就要看该割顶在几个双联通分量里出现过. #pragma comment(linker, "/STACK:10240000,10240000") #include <a

HDU5409---CRB and Graph 2015多校 双联通分量缩点

题意:一个联通的无向图, 对于每一条边, 若删除该边后存在两点不可达,则输出这两个点, 如果存在多个则输出第一个点尽可能大,第二个点尽可能小的. 不存在输出0 0 首先 若删除某一条边后存在多个联通分量则该边一定是桥, 那么我们可以先处理出所有的桥,然后把所有双联通分量缩点,缩点之后就变成了一棵树. 而树上的每一条边都是一个桥, 考虑每条边的输出,删除某一边后肯定会出现两个联通分量, 需要记录两个联通分量中最大的点max1 max2, 如果max1!=n 则答案就是max1 max1+1否则ma

POJ 3177 Redundant Paths 无向图边双联通基础题

题意: 给一个无向图,保证任意两个点之间有两条完全不相同的路径 求至少加多少边才能实现 题解: 得先学会一波tarjan无向图 桥的定义是:删除这条边之后该图不联通 一条无向边(u,v)是桥,当且仅当(u,v)为树枝边,且满足 DFN(u)<Low(v).(因为 v 想要到达 u 的父亲必须经过(u,v)这条边,所以删去这条边,图不连通) 先用Tarjan无向图缩边双联通分量,这样原图就构成了一颗树, 对于树的叶子节点来说,显然他们需要连边,可以证明的是,我们连至多(叶子节点个数+1)/2的边就

边双联通分量

(noip模拟赛)化学竞赛的大奖 (prize.pas/c/cpp) [问题描述] XYX 在 CChO(全国化学奥林匹克竞赛)比赛中获得了大奖,奖品是一张特殊的机票.使用这张机票,可以在任意一个国家内的任意城市之间的免费飞行,只有跨国飞行时才会有额外的费用.XYX 获得了一张地图,地图上有城市之间的飞机航班和费用.已知从每个城市出发能到达所有城市,两个城市之间可能有不止一个航班.一个国家内的每两个城市之间一定有不止一条飞行路线, 而两个国家的城市之间只 有一条飞行路线. XYX想知道, 从每个

双联通分量与二分图

我这是耽搁了多长时间才把它整完哈哈哈哈哈: 双联通分量 在无向图中,如果无论删去哪条边都不能使得 u 和 v 不联通,则称 u 和 v 边双连通: 在无向图中,如果无论删去哪个点(非 u 和 v)都不能使得 u 和v 不联通,则称 u 和 v 点双连通. 割点:删去该点,图分裂为多个连通块. 割边:也叫"桥",删去该边,图分裂为多个连通块. 点双连通分量 类似地,定义$ d f n_u 和 low_u$. 如果 v 是 u 的子结点,并且 $low_v ≥ d f n_u $则点 u

【POJ 2942】Knights of the Round Table(双联通分量+染色判奇环)

[POJ 2942]Knights of the Round Table(双联通分量+染色判奇环) Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 11661   Accepted: 3824 Description Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, an