找割顶的模板

用邻接矩阵写的。自己慢慢理解吧

#include <iostream>
#include <cstring>
using namespace std;
#define CC(c) memset(c, 0, sizeof(c))

const int maxn=5000;

int iscut[maxn], g[maxn][maxn], low[maxn], pre[maxn], _pre, n, m;

int dfs(int u, int fa) {
	low[u]=pre[u]=++_pre; //初始时
	int child=0; //如果child=1并且它是根,就不是割顶
	for(int v=1; v<=n; ++v) if(g[u][v]) {
		if(!pre[v]) {
			child++;
			int lowv=dfs(v, u); //找子女的最小low,看是否能回溯到自己的fa前面
			if(lowv<low[u]) low[u]=lowv; //更新最小
			if(lowv>=pre[u]) iscut[u]=1; //如果在fa后面,即没有指向fa前面,就是一个割顶
		}
		else if(pre[v]<pre[u] && v!=fa && low[u]>pre[v])
			//因为是无向图,所以要判断是否是之前的访问的第二次访问回去的环
			low[u]=pre[v];
	}
	if(fa<0 && child==1) iscut[u]=0;
	return low[u];
}

void find_cut() {
	CC(iscut); CC(low); CC(pre);
	for(int i=1; i<=n; ++i) if(!pre[i]) dfs(i, -1);
	for(int i=1; i<=n; ++i) if(iscut[i]) cout << i << " ";
	cout << endl;
}

int main() {
	cin >> n >> m;
	for(int i=1; i<=n; ++i) {
		int a, b;
		cin >> a >> b;
		g[a][b]=g[b][a]=1;
	}
	find_cut();

	return 0;
}

找割顶的模板,布布扣,bubuko.com

时间: 2024-10-11 20:01:49

找割顶的模板的相关文章

无向图的割顶和桥,无向图的双连通分量入门详解及模板 -----「转载」

https://blog.csdn.net/stillxjy/article/details/70176689 割顶和桥:对于无向图G,如果删除某个节点u后,连通分量数目增加,则称u为图的割顶:如果删除某条边后,连通分量数目增加,则称该边为图的桥.对于连通图删除割顶或桥后都会使得图不再连通 以下我,我们利用dfs的性质来快速找出一个连通图中的所有的割顶和桥 首先我们要引入”时间戳”这个概念: 时间戳:表示在进行dfs时,每个节点被访问的先后顺序.每个节点会被标记两次,分别用pre[],和post

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

P3388 [模板]割点(割顶) 题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式: 第一行输出割点个数 第二行按照节点编号从小到大输出节点,用空格隔开 输入输出样例 输入样例#1: 6 7 1 2 1 3 1 4 2 5 3 5 4 5 5 6 输出样例#1: 1 5 说明 n,m均为100000 tarjan 图不一定联通!!!. 没错我以前就是不会,不服bb别solo #i

图论算法-Tarjan模板 【缩点;割顶;双连通分量】

图论算法-Tarjan模板 [缩点:割顶:双连通分量] 为小伙伴们总结的Tarjan三大算法 Tarjan缩点(求强连通分量) int n; int low[100010],dfn[100010]; bool ins[100010]; int col[100010];//记录每个点所属强连通分量(即染色) vector<int> map[100010]; stack<int> st; int tot;//时间戳 int colnum;//记录强连通分量个数 void tarjan(

【模板】无向图的割顶

无向图的割顶: Vector <int> G[] :邻接表存图 Int pre[] :存储时间戳 Int low[] : u及其后代所能连回的最早的祖先的pre值 Int iscut[] : =true表示是割顶,=false不是割顶 Dfs函数在主函数调用时,fa预设为-1. vector <int> G[MAXN]; int pre[MAXN],iscut[MAXN],low[MAXN],dfs_clock; int dfs(int u,int fa) { int lowu=p

UVA 315 :Network (无向图求割顶)

题目链接 题意:求所给无向图中一共有多少个割顶 用的lrj训练指南P314的模板 #include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=109; struct Edge { int to,next; Edge(){} Edge(int _to,int _next) { to=_to; next=_next; } }edge[N*N*2]; int head[N]; int dfn[N],lo

无向图的割顶和桥

割顶: 关键点,删掉这个点后,图的连通分量 + 1: 桥: 在割顶的基础上,发现删除 (u,v) 这条边,图就变成非连通的了. 如何找出所有割顶和桥: 时间戳: 在无向图的基础上,DFS建树的过程中,各点进栈和出栈的时间 dfs_clock,进栈的时间 pre[],出栈的时间 post[] 在DFS程序中的体现就是: void previst(int u) { pre[u]= ++dfs_clock; } void postvist(int u) { post[u] = ++dfs_clock;

codeforces22c System Administrator【给定一个割顶输出边 BCC】

Description Bob got a job as a system administrator in X corporation. His first task was to connectn servers with the help ofm two-way direct connection so that it becomes possible to transmit data from one server to any other server via these connec

无向图的割顶(poj1523,1144)

割顶:表示无向图中的点,这个点删除之后,原图不在联通,这样的点就是割顶. 怎么求一个图中的割顶呢? 把无向图变成一颗树,dfs时候搜索到在dfs树上的称为树边,搜索是出现后代指向祖先的边称为反向边. 对于根节点,当他存在两个或两个以上的子节点时,那么他就是割顶. 而对于其他节点u,当且仅当u存在一个子节点v,使得v及其所有的后代都没有反向边连回u的祖先时,u是一个割顶. 那么判断就很简单,这里给出两个模板: 题目:poj1523 和 1144都是裸的求割顶的题目 通用模板: #include <

2018/2/11 每日一学 无向图割顶和桥

割顶和桥:对于无向图G,如果删除某个节点u后,连通分量数目增加,则称u为图的割顶:如果删除某条边后,连通分量数目增加,则称该边为图的桥. 对于连通图删除割顶或桥后都会使得图不再连通. 我们利用dfs的性质来快速找出一个连通图中的所有的割顶和桥. 设low[u]为u及其后代所能连回的最早的祖先的pre[]值,pre[]为时间戳则当u存在一个子节点v使得low[v] >= pre[u]时u就为割顶 同理当 low[v] > pre[u]时 u-v为桥 看代码吧(转自http://blog.csdn