首页 > 其他分享 >割点 and 割边

割点 and 割边

时间:2024-08-16 20:39:07浏览次数:8  
标签:head int ios 割点 割边 dfn low include

P3388 【模板】割点

Note:图可能不联通,因此每次tarjan都要更新root

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

#define int long long 
#define ios std::ios::sync_with_stdio(false);std::cin.tie(0); 
const int N = 2e6+9;

using namespace std;


int n,m;
int idx=0,head[N];
int dfn[N],low[N];
int time__=0;
struct node{
    int to,val,next;
}e[N<<1];
int cut[N];
int root;
vector<int>cut_vertex;
void add(int u,int v,int val){
    e[idx] = {v,val,head[u]};
    head[u] = idx++;
}
void bd(){
    cin>>n>>m;
    memset(head,-1,sizeof head);
    for(int i=1;  i<=m ;++i){
        int u,v;
        cin>>u>>v;
        add(u,v,0);
        add(v,u,0);
    }
}
void tarjan(int u) {
    low[u] = dfn[u] = ++time__;
    int child = 0;
    for(int i = head[u]; i != -1; i = e[i].next) {
        int v = e[i].to;
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
            if(low[v] >= dfn[u]){
                child++;
                if(u!=root || child > 1){
                    cut[u]=1;
                }
            }
        } 
        else 
            low[u] = min(low[u], dfn[v]);
    }
}
signed main(){
    ios;
    bd();
    for(int i=1 ; i<=n ;++i)
        if(!dfn[i]){
            root=i;
            tarjan(i);
        }
    int ans=0;
    for(int i=1 ; i<=n ;++i)
        if(cut[i]==1)
            ans++;
    cout<<ans<<"\n";
    for(int i=1 ; i<=n ;++i)
        if(cut[i]==1)
            cout<<i<<" ";
    return 0;
}

T103481 【模板】割边

这次要找边,每次dfs的时候记录他的父节点然后判断一下,不要往回跑

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#define ep emplace_back 

#define int long long  
#define ios std::ios::sync_with_stdio(false);std::cin.tie(0);  
const int N = 2e6+9;
using namespace std;

int n,m;
struct node{
    int to,val,next;
}e[N<<1];
int head[N],idx=0;
int dfn[N],low[N];
int time__=0;
bool vis[N];

void add(int u,int v,int val=0){
    e[idx] = {v,val,head[u]};
    head[u] = idx++; 
}
void bd(){
    cin>>n>>m;
    memset(head,-1,sizeof head);
    for(int i=1 ; i<=m ; ++i){
        int u,v;
        cin>>u>>v;
        add(u,v);
        add(v,u);
    }
}
struct edge{
    int edge,from,to;
};
vector<edge>ee;
void tarjan(int u,int fa){
    low[u] = dfn[u] = ++time__;
    for(int i=head[u] ; i!=-1 ; i=e[i].next){
        int v = e[i].to;
        if(!dfn[v]){
            tarjan(v,u);
            low[u] = min(low[u],low[v]);
            if (low[v] > dfn[u]) {
                ee.push_back(edge{i/2+1,u,v});//加边
            }
        }
        else if(v!=fa)
            low[u] = min(low[u],dfn[v]);
    }
}
signed main(){
    ios;
    bd();
    for(int i=1 ; i<=n ;++i)
        if(!dfn[i])
            tarjan(i,i);

    cout<<ee.size()<<"\n";
    for(auto x:ee){
        //printf("%lld %lld %lld",x.edge,x.from,x.to);
    }
    return 0;
}

标签:head,int,ios,割点,割边,dfn,low,include
From: https://www.cnblogs.com/Phrink734/p/18363599

相关文章

  • 无向图的连通性(割点与割边)
    割点与割边 割点的求解方法  割点详解 板题:https://www.luogu.com.cn/problem/P3388  第1题   割点 查看测评数据信息给出一个n个点,m条边的无向图,求图的割点。输入格式 第一行输入两个正整数n,m。下面m行每行输入两个正整数x,y表示x到y有一......
  • C++的算法:割点与割边
            在图论中,割点与割边是图的重要性质,它们在图的连通性、网络流等问题中扮演着关键角色。在C++中,我们可以通过深度优先搜索(DFS)等算法来判定一个图中的割点与割边。        割点,又称关节点或桥接点,是指在无向连通图中,如果删除某个顶点后,图的连通分量数增......
  • 【图论】割点(割顶)
    前置定义有无向图\(G=(V,E).\)无向图的DFS树:从某一点\(root\)开始DFS,访问邻点\(.\)当搜索到点\(u\)时,我们遍历每一条以\(u\)为起点的边\((u,v_i)\),且定义有向边\(u\longrightarrowv_i.\)于是DFS的过程全部完成之后,所有被定义的有向边就会组成一颗以\(r......
  • 图论-割边与边双连通分量
    首先是两篇模板割边点击查看代码inthead[N],cnt=1;structEdge{intfrom,to,nxt;}e[N<<1];voidadd(intu,intv){e[++cnt].from=u;e[cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt;}intdfn[N],back[N],tim,bri_cnt;//dfn......
  • 图论-割点与点双连通分量
    首先是两篇的代码割点点击查看代码inthead[N],cnt=0;structEdge{intfrom,to,nxt;}e[N<<1];voidadd(intu,intv){e[++cnt].from=u;e[cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt;}intdfn[N],back[N],tim;//dfn[i]时......
  • 图论-割点与割边
    这是摘自算法书上的一篇Tarjan求割点算法dfn[i]代表时间戳数组back[i]代表该点不依靠祖先节点能回到的最远的祖先节点采用链式前向星建图,结果存储在iscut[]数组中点击查看代码inthead[N],cnt=0;structEdge{intfrom,to,nxt;}e[N<<1];voidadd(......
  • 桥、割点和边双连通分量
    桥定义:删除后会增加联通块数量的边被称作桥。那么,如何求解呢?方法一首先跑出一颗dfs树。比如下图(\(2-6,1-5\)的边是非树边):可以发现,所有非树边和其构成的环上的所有边不可能是桥,因为删去后仍可以通过环的另一半。比如上图中只有\(1-2\)一个桥。那是不是除了这些边以外都是......
  • 割点
    割点割点是如果删除这个点,连通块+1的点就是割点。可以发现,在DFS树上,如果一个点的儿子不能通过一些非树边到达它的父亲,如果把它删除,这个儿子将会和他的父亲不连通。#include<bits/stdc++.h>usingnamespacestd;constintN=2e5+5;intlow[N],cnt,dfn[N......
  • 图论割点模板
    #include<iostream>#include<vector>#include<algorithm>#include<math.h>#include<sstream>#include<string>#include<string.h>#include<iomanip>#include<stdlib.h>#include<map>#include<queue......
  • P3388 【模板】割点(割顶)
    原题链接题解先说结论对单个图做深度搜索树,对于树的根节点,它要能是割点当且仅当她有至少两个不互通的儿子节点对于树的非叶子非根节点,它要能是割点当且仅当存在儿子节点能去的时间戳最小的节点不小于当前节点的深度搜索序对于叶子节点,不可能成为割点code#include<bits/std......