点双联通分量和边双联通分量如何选择?

news2024/11/13 13:07:59

先讲一下 ,双联通分量 一定是用于 无向图
考虑什么时候需要用边双联通分量呢?,考虑给你的是一个一般图,需要你把联通的点都缩起来,视作一个点的情况,就是说割点可以反复访问,就是说割点和其他点都是等效的,并没有区别,,(正常情况都是边双联通分量,如果出到点双连通分量,一般难度很高)

点双联通分量使用时,通常,有些点有些特殊,比如,你通过一个环,必须得从一个点入,另一个点出,像下面图,无法通过这个环从1抵达6,这种的情况就需要用点双联通分量缩点图1
再点双之中,这种可以通过环来从1抵达6
在这里插入图片描述
但是在边双中两图完全没有区别
以后可以试试这两种走法是否有区别来判断使用点双还是边双

边双

/*
*/
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define sqrt(a) sqrtl(a)
#define abs(a) llabs(a)
#define pow(a) powl(a)
typedef  pair<int,int> pi ;
#define if1(x) for(int i =1 ;i<=x;i++)
#define if0(x) for(int i = 0;i<x;i++)
#define jf0(x) for(int j = 0;j<x;j++)
#define jf1(x) for(int j = 1;j<=x;j++)
#define pb push_back
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const int N = 2e5+10;



vector<pair<int,int>> edg[N];//终点和边的编号
vector<int> nedg[N];//新边图
int id[N];
int dfn[N],low[N],tim;
stack<int> stk;
vector<vector<int> > dcc;//边双连通分量
bool vis[N];
int cnt,idx;
int n,m;//点数目,边数目
int nidx ;//新点的编号
void tarjan(int u,int in_edg)
{
    dfn[u] = low[u] = ++tim;//更新时间戳
    stk.push(u);vis[u] = 1;
    for(auto &j:edg[u]){
        if(j.second ==(in_edg^1))continue;//是回边,则不走
        if(!dfn[j.first]){//没有访问
            tarjan(j.first,j.second);
            low[u] = min(low[u],low[j.first]);
        }else if(vis[j.first])
            low[u] = min(low[u],low[j.first]);
    }
    if(dfn[u] == low[u]){//桥边到了
        vector<int>te;
        while(1){
            int y = stk.top();stk.pop();
            te.push_back(y);
            vis[y] = 0;
            if(u == y)break;
        }dcc.push_back(te);     
    }
}
void suodian(){
    for(auto j:dcc){
        nidx++;
        for(auto k:j)id[k] = nidx;//标记点的联通 块属于谁
    }
    if1(n){
        for(auto [a,b]:edg[i]){
            if(id[i]!=id[a]){
                nedg[id[i]].push_back(id[a]);
            }
        }
    }
}
void solve(){
    cin>>n>>m;
    idx = 0;
    if0(m){
        int a,b;
        cin>>a>>b;
        edg[a].push_back({b,idx++});
        edg[b].push_back({a,idx++});
    }
    if1(n){
        if(!dfn[i])tarjan(i,-1);
    }
    suodian();
    if1(n)cout<<i<<" "<<id[i]<<"||";
    cout<<endl;
    //输出新图
    if1(nidx){
        cout<<i<<":";
        for(auto j:nedg[i])cout<<j<<" ";
        cout<<endl;
    }

}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr); 
    int t=1;
    // cin>>t;
    while (t--)
    {
        solve();
    }
    return 0;
}
/*
9 11
1 2
2 3
3 1
1 4
1 5
5 6
4 7
1 7
2 7
5 8
9 6
输出
初始边和新边
1 5||2 5||3 5||4 5||5 4||6 2||7 5||8 3||9 1||
新图
1:2
2:4 1
3:4
4:5 2 3
5:4

*/

点双

/*
*/
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define sqrt(a) sqrtl(a)
#define abs(a) llabs(a)
#define pow(a) powl(a)
typedef  pair<int,int> pi ;
#define if1(x) for(int i =1 ;i<=x;i++)
#define if0(x) for(int i = 0;i<x;i++)
#define jf0(x) for(int j = 0;j<x;j++)
#define jf1(x) for(int j = 1;j<=x;j++)
#define pb push_back
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const int N = 2e5+10;




vector<int> edg[N];//终点和边的编号
set<int>  nedg[N];
int dfn[N],low[N],tim;
stack<int> stk;
vector<int > dcc[N];//点双连通分量
bool cut[N];//割点
int id[N];
int cnt,idx,root,nidx;
int n,m;//点数目,边数目
void tarjan(int u)
{
    dfn[u] = low[u] = ++tim;//更新时间戳
    stk.push(u);
    if(!edg[u].size()){//孤立点
        dcc[++cnt].push_back(u);return;
    }
    int child = 0;
    for(auto  j:edg[u]){
        if(!dfn[j]){
            tarjan(j);
            low[u] = min(low[u],low[j]);
            if(low[j] >= dfn[u]){
                child++;
                if(u!=root||child>1){
                    cut[u] = 1;//是割点
                }
                cnt++;
                while(1){
                    int z = stk.top();stk.pop();
                    dcc[cnt].push_back(z);
                    if(z == j)break;
                }
                dcc[cnt].push_back(u);
            }
        }
        else{
            low[u] = min(low[u],dfn[j]);
        }
    }

}
void suodian(){
    nidx = cnt;
    if1(n*m){
        if(cut[i]){
            id[i] = ++nidx;//给割点重新编号

        }
    }
    if1(cnt){
        // cout<<i<<":";
        for(auto j:dcc[i]){
            if(cut[j] == 1){
                nedg[i].insert(id[j]);
                nedg[id[j]].insert(i);
            }
            //割点已经编好新下标了
            else id[j] = i;//以连通块序号来对块中顶点编号
            // cout<<j<<" "<<id[j]<<",";

        }
        // cout<<endl;
    }
}
void solve(){
    cin>>n>>m;
    if0(m){
        int a,b;
        cin>>a>>b;
        edg[a].push_back(b);
        edg[b].push_back(a);
    }
    if1(n){
        if(!dfn[i])root = i,tarjan(i);
    }
    suodian();
    if1(n)cout<<i<<" "<<id[i]<<"||";
    cout<<endl;
    //输出新图
    if1(nidx){
        cout<<i<<":";
        for(auto j:nedg[i])cout<<j<<" ";
        cout<<endl;
    }
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr); 
    int t=1;
    // cin>>t;
    while (t--)
    {
        solve();
    }
    return 0;
}
/*
8 10
1 2
3 4 
2 3
2 4
1 4
1 5
5 6
5 7
5 8
7 8

*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1983596.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙应用服务开发【华为支付服务】 服务端

介绍 华为支付云侧接口 Java SDK Sample。 官方 Java 语言开发库pay-java由 core 和 service 组成&#xff1a; core 为基础库。包含自动签名和验签的 HTTP 客户端、回调处理、加解密库。service 为业务服务。基于业务场景提供不同的业务类&#xff0c;其下的方法为对应的ht…

openai-dotnet:OpenAI官方提供的.NET SDK库!

自从ChatGPT大火以来&#xff0c;针对OpenaAI提供的API接口&#xff0c;封装的SDK库非常多。 之前也推荐过几个.Net版本&#xff0c;今天推荐下OpenAI官方提供的.NET 库&#xff01; 01 项目简介 openai-dotnet是OpenAI 官方提供的 .NET库&#xff0c;用于方便.NET应用程序中…

【Java数据结构】---初始数据结构

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 &#xff0c;Java 欢迎大家访问~ 创作不易&#xff0c;大佬们点赞鼓励下吧~ 前言 从今天开始我们就要学习Java…

搭建基于树莓派的Linux学习环境(TODO)

主要是想学一下Linux内核&#xff0c;所以搭一套环境&#xff0c;其实有几个选择&#xff0c;都是我买了板子的。 首先是正点原子的RK3568&#xff0c;最早是想弄安卓&#xff0c;但是SDK的大小真的把我劝退了&#xff0c;动不动几百个G的空间&#xff0c;还有就是保底16个G的…

108 将有序数组转换为二叉搜索树

解题思路&#xff1a; 平衡二叉树&#xff0c;又称自平衡二叉搜索树&#xff08;简称AVL树&#xff09;&#xff0c;其特点如下: 每个子树都为平衡二叉树高度平衡&#xff1a;任意节左子树与右子树高度差不超过1排序树&#xff1a;左子树的所有节点的值小于该节点&#xff0c;…

算法回忆录(3)

11. 假设有7个物品&#xff0c;它们的重量和价值如下表所示。若这些物品均不能被分割&#xff0c;且背包容量M&#xff1d;150&#xff0c;设计算法求解怎么装才能使得获取的价值最大&#xff1f;请写出伪代码。 #include <stdio.h>#define MAX_ITEMS 100 #define …

怎么读取FRM、MYD、MYI数据文件

一、介绍frm、MYD、MYI文件 在MySQL中&#xff0c;使用MyISAM存储引擎时&#xff0c;数据库表会被分割成几个不同的文件文件描述功能扩展名FRM 文件表结构定义文件存储表的结构信息&#xff0c;字段、索引等.FRMMYD 文件数据文件包含表的实际数据.MYD&#xff08;MYData&#x…

Vue3安装ffmpeg做视频截取报错

通过 yarn 安装 ffmpeg 时报错。 即&#xff0c;执行以下指令时报错&#xff1a; yarn add ffmpeg/ffmpeg^0.10.0 yarn add ffmpeg/core^0.10.0错误信息&#xff1a; node_modules\pngquant-bin: Command failed. Error: pngquant failed to build, make sure that libpng-d…

Unity强化工程 之 SpriteRender

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正 1.SpriteRenderer是什么 渲染精灵用的&#xff0c;是渲染的核心组件&#xff0c;有许多重要参数所以要详细讲一讲 Spri…

从数据孤岛到一体化平台:PLM系统的变革之路

在当今快速变化的商业环境中&#xff0c;产品生命周期管理&#xff08;Product Lifecycle Management, PLM&#xff09;系统已成为企业提升竞争力、加速产品创新、优化资源配置的关键工具。相较于传统的产品数据管理&#xff08;Product Data Management, PDM&#xff09;系统和…

WPF MVVM模式图片占用问题

在很久以前就遇到这个问题&#xff0c;当时解决了&#xff0c;这过了几年&#xff0c;又遇到这个问题&#xff0c;这里做个总结&#xff0c;防止下次再踩坑了&#xff0c;也顺便帮助一下同样遇到这个问题的朋友 。 出现这个问题的原因是&#xff1a;将文件路径绑定到Image的Sou…

BUUCTF [安洵杯 2019]easy_serialize_php 1

打开题目&#xff0c;看到一串php代码&#xff0c;试着代码审计一下&#xff0c;看一下有用信息 可以看出是通过$_SESSION[img]来读取文件 extract可以将数组中的变量导入当前变量表 也就是说我们可以伪造$_SESSION 数组中的所有数据 这里传递一个参数fphpinfo 先用hackbar进…

软件工程课程实习报告(仅供参考)

一&#xff1a;实习内容设计与实现&#xff1a; 实习一&#xff1a;Git分布式版本控制 本实验的主要目的是学习和掌握Git作为版本控制工具的基本使用方法&#xff0c;特别是在团队协作开发中的重要性。具体目标包括&#xff1a; 1. 理解Git的基本概念和工作原理&#xff0c;…

【AI】可变形卷积Deformable Conv

卷积对大家来说并不陌生了&#xff0c;这里主要描述Deformable Conv。其在论文中也是常见的一个术语&#xff0c;Deformable Convolutional Networks(DCN) 还可以细分成可变形卷积、对候选区域的池化等。 传统卷积操作 将特征图分成一个个与卷积核大小相同的部分&#xff0c;…

k8s—部署dashboard可视化界面

1、下载recommended.yaml配置文件 1&#xff09;根据自己安装的kubernetes版本安装适配的dashboard 我安装的kubernetes是1.24.2版本的&#xff0c;需要安装v:2.6.1版本的dashboard 2&#xff09;下载地址&#xff1a;https://raw.githubusercontent.com/kubernetes/dashboa…

【机器学习】神经网络的无限可能:从基础到前沿

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 引言 在当今人工智能的浪潮中&#xff0c;神经网络作为其核心驱动力之一&#xff0c;正以前所未有的速度改变着我们的世界。从图像识别到自然语言处理&#xff0c;从自动驾驶到医疗诊断&#xff0c;神经网络的…

electron 配置、打包 -报错解决

目录 一、配置途中遇到的问题&#xff1a; 二、 make 配置好后开始打包 三、Electron-builder 打包报错 一、配置途中遇到的问题&#xff1a; 1. 安装 yarn add electron -D 一直卡在这里失败 一直卡可以使用下面这个&#xff0c;然后再重新装依赖 1. 采用新的镜像地址 npm …

proteus仿真c51单片机(二)中断控制流水灯(电路设计及代码)

实验要求 8路流水灯&#xff0c;K1和K2都未按下时&#xff0c;主程序执行LED流水灯程序&#xff0c;K1按下时&#xff0c;左右4只LED交替闪烁&#xff0c;K2按下时8只LED全部闪烁4次&#xff0c;设置外部中断1为高优先级。 实验步骤 1、打开PROTEUS软件选取元件&#xff0c…

未授权访问漏洞(重点版─=≡Σ(((つ•̀ω•́)つ)

1.* Redis 搭建靶场环境&#xff1a; 进入目录:cd/vulhub-master/redis/4-unacc 启动:docker-compose up-d 检查:docker-compose ps vi docker-compose.yml //查看端口和版本号 安装redis工具 在kali上安装redis进行服务链接 #安装redis apt-get install redis #redi…

GD 32 IIC 驱动代码

前言&#xff1a; 学会IIC驱动的原理&#xff0c;时序和代码实现 1.0 GPIO初始化 从原理图中可以看出IIC对应的时钟线和数据线在PB端口&#xff0c;因此需要初始化GPIOB的时钟&#xff0c;同时初始化GPIOB_PIN_6 | 7,的引脚&#xff0c;设置为开漏输出模式。 什么事开漏&…