首页 > 其他分享 >缩点学习笔记

缩点学习笔记

时间:2023-02-03 15:23:50浏览次数:61  
标签:缩点 int scc 笔记 学习 dfn low 分量

假如题目名称不是“【模板】缩点”的话,是否能想到缩点?

这道题如何联想到缩点?

首先题目给出的图,可能存在强连通分量,这样的强连通分量中,所有的点权都可全部取到,所以如果走到分量之中的一个点,那么整个分量的点权都可以加上,且题目说点权非负了。这样缩点之后优化了空间时间,也避免了在连通分量中重复兜圈。

那么进行tarjan算法缩点。这里称每个强连通分量为团。每个团上存储的是团内点权之和。缩点后重新建图,创立新的邻接表。每个团的权都是非负,这里就利用到了DAG的性质是无环的(废话),所以对其进行拓扑排序,进行基本的dp,将最大值递推下去即可。

这里总结一下一般的缩点题型的特征:

  • 强连通分量
  • 数据大多在点上
  • 点不可以重复,边可以重复
  • 与之后的DAG有关
  • ……
#include <bits/stdc++.h>

using namespace std;
const int N = 10005;
vector<int>e[N];
vector<int>ne[N];
stack<int>stk;
queue<int>q;
bitset<N>instk;
int dfn[N], low[N], tot;
int scc[N], siz[N], scc_sum[N], cnt;
int deg_in[N], deg_out[N];
int w[N];
int dp[N];
int n, m;
void tarjan(int u)
{
	dfn[u] = low[u] = ++ tot;
	stk.push(u);
	instk[u]= 1;
	for (int v : e[u]) {
		if (!dfn[v]) {
			tarjan(v);
			low[u] = min(low[v], low[u]);
		} else if (instk[v]) {
			low[u] = min(low[u], dfn[v]);
		}
	}
	if (low[u] == dfn[u]) {
		int v;
		++cnt;
		do {
			v = stk.top();
			stk.pop();
			instk[v] = 0;
			scc[v] = cnt;
			scc_sum[cnt] += w[v];
		} while (v != u);
	}
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int  i = 1; i <= n; i++) {
		scanf("%d", &w[i]);
	}
	for (int i = 1, a, b; i <= m; i++) {
		scanf("%d%d", &a, &b);
		e[a].push_back(b);
	}
	for (int i = 1; i <= n; i++) {
		if (!dfn[i]) {
			tarjan(i);
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int v : e[i]) {
			if (scc[i] != scc[v]) {
				ne[scc[i]].push_back(scc[v]);
				deg_in[scc[v]] ++;
				deg_out[scc[i]] ++;
			}
		}
	}
	for (int i = 1; i <= cnt; i++) {
		if (deg_in[i] == 0) {
			q.push(i);
			dp[i] = scc_sum[i];
		}
	}
	while (q.size()) {
		int u = q.front();
		q.pop();
		for (int v : ne[u]) {
			dp[v] = max(dp[v], dp[u] + scc_sum[v]);
			deg_in[v] --;
			if (deg_in[v] == 0)
				q.push(v);
		}
	}
	int ans = 0;
	for (int i = 1; i <= cnt; i++) {
		ans = max(ans, dp[i]);
	}
	printf("%d\n", ans);
	return 0;
}

标签:缩点,int,scc,笔记,学习,dfn,low,分量
From: https://www.cnblogs.com/CYLSY/p/17089376.html

相关文章

  • 狂神说Springboot笔记
    狂神说SpringBoot视频链接:B站教学视频SpringBoot系列笔记:狂神说SpringBoot01:Hello,World!狂神说SpringBoot02:运行原理初探狂神说SpringBoot03:yaml配置注入狂神......
  • 西湖论剑2023学习笔记
    太菜了打不了比赛,跟着师傅们的wp学习一下NodeMagicalLoginflag1functionFlag1Controller(req,res){try{if(req.cookies.user===SECRET_COOKIE)......
  • ubuntu18安装vsftpd无坑笔记
    环境ubuntu18.04server版,折腾了两天,千山万水淌过来的,分享给大家,少走弯路1.安装sudoaptinstallvsftpd2.配置vim/etc/vsftpd.confanonymous_enable=NOlocal_enable=Y......
  • Markdown语法与Typora基础操作学习
    在2.2~2.3的两天时间内,我学习了Markdown语法,并且将其实践于Typora之中。在学习的过程中,Typora带给了我意想不到的惊喜,比起印象笔记和OneNote的功能,Typora丰富的快捷键设置......
  • 【学习笔记】多项式学习笔记2:集合幂级数
    点击查看目录目录集合幂级数定义运算应用子集相关运算高位前(后)缀和高维前(后)缀差分快速莫比乌斯变换\(\text{FMT(FsatMobiusTransform)}\)或卷积(集合并卷积)与卷积(集合......
  • Go 语言学习之路(笔记)
    将大佬的博客整理成相关目录。查找方便go语言安装及介绍go语言环境搭建go语言基础之变量和常量go语言基础之基本数据类型go语言基础之运算符go语言基础之流程控制Go......
  • DTD 学习
    DTD教程目录目录DTD教程目录DTD简介DTD是什么?DTD与XML的关系?为什么使用DTD?内部DTD外部DTDXML构建模块元素属性实体PCDATACDATADTD元素DTD属性DTD实体参考......
  • 笔记:海量数据的查询方法
    概述:每年大约有几千万近一亿的业务数据量,如何提高查询性能。具体方案:在表结构初始化阶段时,需要添加查询条件的索引;并且可以使用uuid主键和数字主键的联合业务主键,根据......
  • (笔记)【NTP系列:06】NTP报文解读
    一、概念NTP(NetworkTimeProtocol),互联网时间协议。 UTC(CoordinatedUniversalTime),协调通用时间。根据原子振荡周期所计算的物理时钟,这种计算方式对于时间的计算误差......
  • 快速傅里叶变换学习简记
    多项式部分是OI中一个比较math和naive的部分,各种多项式题声(chou)名(ming)远(zhao)扬(zhu)。因为作者数学较弱,因此这篇文章会比较注重数学部分的理解。同时感谢所......