首页 > 其他分享 >Tarjan整理

Tarjan整理

时间:2024-03-16 14:22:19浏览次数:25  
标签:Tarjan int 1000005 cnt dfn low 整理 include

求强连通分量个数

#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
struct sss{
	int t, ne;
}e[1000005];
int h[1000005], cnt;
void add(int u, int v) {
	e[++cnt].ne = h[u];
	e[cnt].t = v;
	h[u] = cnt;
}
int dfn[1000005], low[1000005];
int num, su;
bool vis[1000005];
int belog[1000005];
stack<int> s;
int d[1000005];
int sum[1000005];
void tarjan(int x) {
	dfn[x] = low[x] = ++num;
	vis[x] = true;
	s.push(x);
	for (int i = h[x]; i; i = e[i].ne) {
		int u = e[i].t;
		if (!dfn[u]) {
			tarjan(u);
			low[x] = min(low[x], low[u]);
		} else if (vis[u]) {
			low[x] = min(low[x], dfn[u]);
		}
	}
	if (dfn[x] == low[x]) {
		su++;
		int t = 0;
		do {
			t = s.top();
			s.pop();
			sum[su]++;
			belog[t] = su;
			vis[t] = false;
		} while(t != x);
	}
}
int n, m;
int main() {
	scanf("%d %d", &n, &m);
	int x, y;
	for (int i = 1; i <= m; i++) {
		scanf("%d %d", &x, &y);
		add(x, y);
	}
	for (int i = 1; i <= n; i++) {
		if (!dfn[i]) tarjan(i);
	}
	printf("%d", su);
	return 0;
}

Tarjan缩点

例题:ATM受欢迎的牛

以前者为例;

#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
int n, m, st, p;
struct sss{
	int t, ne;
}e[1000005], edge[1000005];
int h[1000005], cnt;
void add(int u, int v) {
	e[++cnt].ne = h[u];
	h[u] = cnt;
	e[cnt].t = v;
}
int he[1000005], ccnt;
void add_2(int u, int v) {
	edge[++ccnt].ne = he[u];
	he[u] = ccnt;
	edge[ccnt].t = v;
}
vector<int> vec;
bool v[1000005], vis[1000005];
int dfn[1000005], low[1000005];
int a[1000005];
int num, su;
int sum[1000005];
stack<int> s;
int start;
int belog[1000005];
void tarjan(int x) {
	dfn[x] = low[x] = ++num;
	vis[x] = true;
	s.push(x);
	for (int i = h[x]; i; i = e[i].ne) {
		int u = e[i].t;
		if (!dfn[u]) {
			tarjan(u);
			low[x] = min(low[x], low[u]);
		} else if (vis[u]) {
			low[x] = min(low[x], dfn[u]);
		}
	}
	if (dfn[x] == low[x]) {
		su++;
		int t = 0;
		do {
			t = s.top();
			s.pop();
			belog[t] = su;
			sum[su] += a[t];
			vis[t] = false;
			if (v[t]) vec.push_back(su);
			if (t == st) start = su;
		} while(t != x);
	}
}
int dis[1000005], vvis[1000005];
void SPFA(int x) {
	memset(vvis, 0, sizeof(vvis));
	queue<int> q;
	vvis[x] = true;
	q.push(x);
	while(!q.empty()) {
		int t = q.front();
		q.pop();
		vvis[x] = false;
		for (int i = he[t]; i; i = edge[i].ne) {
			int u = edge[i].t;
			if (dis[u] < dis[t] + sum[u]) { //不要吧u写成i!
				dis[u] = dis[t] + sum[u];
				if (!vvis[u]) {
					q.push(u);
					vvis[u] = true;
				}
			}
		}
	}
}
int main() {
	scanf("%d %d", &n, &m);
	int x, y;
	for (int i = 1; i <= m; i++) {
		scanf("%d %d", &x, &y);
		add(x, y);
	}
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
	}
	scanf("%d %d", &st, &p);
	for (int i = 1; i <= p; i++) {
		scanf("%d", &x);
		v[x] = true;
	}
	for (int i = 1; i <= n; i++) {
		if (!dfn[i]) tarjan(i);
	}
	for (int i = 1; i <= n; i++) {
		for (int j = h[i]; j; j = e[j].ne) {
			int u = e[j].t;
			if (belog[i] != belog[u]) {
				add_2(belog[i], belog[u]);
			}
		}
	}
	for (int i = 1; i <= su; i++) dis[i] = sum[i];
	SPFA(start);
	int ma = -1;
	for (int i = 0; i < vec.size(); i++) {
		ma = max(ma, dis[vec[i]]);
	}
	printf("%d", ma);
	return 0;
}

求割点

例题:备用交换机

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std;
int n;
struct sss{
	int t, ne;
}e[10000005];
int h[10000005], cnt;
void add(int u, int v) {
	e[++cnt].ne = h[u];
	h[u] = cnt;
	e[cnt].t = v;
}
stack<int> s;
int dfn[1000005], low[1000005];
int d[1000005];
bool vis[1000005], cd[1000005];
int num;
int sum;
int root;
void tarjan(int x) {
	dfn[x] = low[x] = ++num;
	int son = 0;
	s.push(x);
	vis[x] = true;
	for (int i = h[x]; i; i = e[i].ne) {
		int u = e[i].t;
		if (!dfn[u]) {
			son++;
			tarjan(u);
			low[x] = min(low[x], low[u]);
			if (low[u] >= dfn[x]) {
				if (x != root || son > 1) cd[x] = true;
			}
		} else  {
			low[x] = min(low[x], dfn[u]);
		}
	}
	
}
int main() {
	scanf("%d", &n);
	int x, y;
	while(scanf("%d %d", &x, &y) != EOF) {
		add(x, y);
		add(y, x);
	}
	for (int i = 1; i <= n; i++) {
		if (!dfn[i]) {
			root = i;
			tarjan(i);
		}
	}
	for (int i = 1; i <= n; i++) {
		if (cd[i]) sum++;
	}
	printf("%d\n", sum);
	for (int i = 1; i <= n; i++) {
		if (cd[i]) printf("%d\n", i);
	}
	return 0;
}

求割点与乘法原理的结合

标签:Tarjan,int,1000005,cnt,dfn,low,整理,include
From: https://www.cnblogs.com/PeppaEvenPig/p/18077036

相关文章

  • mysql学习整理所有问题
    mysql中的者则表达式(也算做是模糊查询)使用//.来匹配有.的字符 数字或者字母后边加上?表示数字或者字母可选还是不可选  拼接字符串concat()  文本处理函数  同时指定两个列进行全文搜索(前提是这两个列必须增加索引)和against(“”inboolenmode)进行连用......
  • tarjan模板
    信息传递题目描述tarjan模板点击查看代码voidtarjan(intx){ dfn[x]=low[x]=++num; stk.push(x); v[x]=1; for(inti=h[x];i;i=nxt[i]) { if(!dfn[to[i]]) { tarjan(to[i]); low[x]=min(low[x],low[to[i]]); } elseif(v[to[i]]) { low[x]=min(lo......
  • 效率工具整理
    前言每次使用新设备,最最最讨厌的就是配环境,程序员懂得都懂,特别是笔者这种有强迫症的,一定要都配好了才能开始工作,痛定思痛,写一个一键配置的脚本,方便平常环境迁移。该脚本主要包含了日常工作使用的cli工具和各语言环境,每个都写好了安装指令,都是笔者常用的配置,直接运行也可以,会跳过......
  • 2024最新整理Python入门教程(超详细),从零基础入门到精通,看完这一篇就够了
    前言本文罗列了Python零基础入门到精通的详细教程,内容均以知识目录的形式展开。01.python由来与发展介绍02.项目开发流程【文末有惊喜福利......
  • 【基础知识整理】时间复杂度 & 空间复杂度
    原文链接:https://blog.csdn.net/fumeidonga/article/details/131070661时间复杂度是指执行算法所需时间的增长率,而空间复杂度则是指执行算法所需存储空间的增长率。一、时间复杂度通常与输入数据进行比较,时间复杂度不是指具体的时间,而是算法的运算次数,是相对于问题规模的相对量......
  • 2024年最新腾讯云优惠券获得方法整理
    腾讯云作为国内领先的云服务提供商,其优质的产品和服务深受用户喜爱。而腾讯云优惠券则是用户在使用腾讯云服务时能够享受到的一项福利,可以有效降低上云成本。那么,2024年如何获得腾讯云优惠券呢?本文将为大家详细整理最新腾讯云优惠券获得方法。方法一:腾讯云官网活动页面腾讯......
  • 必知必会——SQL语句基本语法整理
     一、数据库表1.新建数据库2.新建数据库表createtable表名(列名1数据类型[约束条件],列名2数据类型[约束条件],……)'''创建一个demo1表a列数据类型为int,是主键b列数据类型为char,该列的数据必须唯一不可重......
  • GaussDB的gs_dump工具问题整理,疑似BUG
     GaussDB的gs_dump工具问题整理,疑似BUG 目前分布式GaussDB用起来问题感觉巨多啊。版本信息如下:09:04:11root@postgres>selectversion();-[RECORD1]-----------------------------------------------------------------------------------------------------------......
  • Oracle创建用户,授权,取消授权常用语句整理
    --删除用户及及用户下的所有数据dropuserxxxcascade;--创建用户赋予密码createuserxxxidentifiedby1234;--赋予权限grantdbatoxxx;--删除权限revokedbafromxxx;--赋予用户登录数据库的权限grantcreatesessiontoxxx;--授予用户操作表的权限gran......
  • tarjan 各类板子集合
    tarjan大板子(非讲解):1、普通缩点DGAvoidtarjan(intx){ dfn[x]=low[x]=++cntp; q.push(x);v[x]=1; for(inti=head[x];i;i=bi[i].next){ intj=bi[i].to; if(!dfn[j]){ tarjan(j); low[x]=min(low[x],low[j]); } elseif(v[j])low[x]=min(low[x],dfn[j]); }......