信息学奥赛一本通 1514:【例 2】最大半连通子图 | 洛谷 P2272 [ZJOI2007] 最大半连通子图

【题目链接】

ybt 1514:【例 2】最大半连通子图
洛谷 P2272 [ZJOI2007] 最大半连通子图

【题目考点】

1. 图论:强连通分量 缩点
2. 图论:拓扑排序 有向无环图动规

【解题思路】

对于图中任意两顶点u、v,满足u到vv到u有路径,该图就是单向连通图。本题中的半连通图,指的就是单向连通图。
导出图,指的是选择顶点之间的所有边也都必须选择。
该题求图中最大的半连通子图,而且该图必须是导出图,也就是选择顶点数最多的单向连通子图,而且要同时选择选出顶点之间所有的边。
强连通图一定是单向连通图,因此可以不用考虑各个强连通分量内部的情况,可以将每个强连通分量视为一个顶点,进行缩点。缩点后,每个顶点(强连通分量)的权值是该强连通分量中顶点数量。
有向无环图中的单向连通子图中的顶点一定是图中一条路径上的顶点。

反证法:一条路径上的顶点是 A 1 , A 2 , . . . , A m A_1,A_2,...,A_m A1,A2,...,Am,假设存在顶点 B B B,顶点 B B B和顶点 A 1 , A 2 , . . . , A m A_1,A_2,...,A_m A1,A2,...,Am不会构成一条路径, A 1 , A 2 , . . . , A m , B A_1,A_2,...,A_m,B A1,A2,...,Am,B的导出图是一个单向连通图。

  • 如果顶点 B B B到顶点 A 1 A_1 A1有边,则 B , A 1 , A 2 , . . . , A m B,A_1,A_2,...,A_m B,A1,A2,...,Am是一条路径,不符合假设。而该图是单向连通图,如果顶点 B B B到顶点 A 1 A_1 A1没有路径,那么必然存在顶点 A 1 A_1 A1到顶点 B B B的路径。
  • 如果顶点 B B B到顶点 A 2 A_2 A2有边,则 A 1 , B , A 2 , . . . , A m A_1,B,A_2,...,A_m A1,B,A2,...,Am是一条路径,不符合假设。而该图是单向连通图,如果顶点 B B B到顶点 A 2 A_2 A2没有路径,那么必然存在顶点 A 2 A_2 A2到顶点 B B B的路径。
  • 依此类推,顶点 A 1 A_1 A1 A 2 A_2 A2、…、 A m − 1 A_{m-1} Am1到顶点B都有路径。
    如果顶点 A m A_m Am到顶点 B B B有边,那么 A 1 , A 2 , . . . , A m , B A_1,A_2,...,A_m,B A1,A2,...,Am,B是一条路径,不符合假设。
    如果顶点 B B B到顶点 A m A_m Am有边,那么 A 1 , A 2 , . . . , A m − 1 , B , A m A_1,A_2,...,A_{m-1},B,A_m A1,A2,...,Am1,B,Am是一条路径,不符合假设。
    因此假设不成立,原命题得证。

在缩点后的图中,找到点权加和最大的路径,选择该路径上的顶点(强连通分量)在原图中对应的顶点,以及这些顶点之间的边构成的子图,就是原图中的最大半连通子图。
缩点后图中点权加和最大路径的点权加和,就是原图中最大半连通子图包含的顶点数量。
而后还需要求最大半连通子图的数量,这里可以通过统计点权和为最大路径点权和的路径数量,来统计半连通子图的数量。
两个连通分量中可能有多条边相连,缩点后的图中两个顶点之间就可能有多条边,即为重边。如果缩点后的图中保留重边,假设顶点A到顶点B有两条重边,那么顶点A到顶点B会被认为有两条路径。而本题实际求的是半连通子图的数量,半连通子图必须是导出图,这里选择了顶点A和顶点B,那么顶点A、B之间的所有边都必须被选择,实际只有一个半连通子图。为了使路径数量和半连通子图一致,本题必须
在缩点后的图中去掉所有重边,此处可以使用与离散化类似的方法完成对重边去重。
接下来就是在缩点后的图中,求有向无环图中点权加和最大的路径的点权加和,具体方法见该题:
信息学奥赛一本通 1262:【例9.6】挖地雷 | 洛谷 P2196 [NOIP1996 提高组] 挖地雷
d p [ i ] dp[i] dp[i]表示以顶点i为终点的点权加和最大的路径的点权加和,在拓扑排序过程中可以求出 d p dp dp数组的值。求 d p dp dp数组最大值的下标为 m x i mxi mxi,顶点 m x i mxi mxi就是点权加和最大的路径的终点。 d p [ m x i ] dp[mxi] dp[mxi]就是第一个要输出的解。

为了求出最大半连通子图的数量,在拓扑排序时还需要进行另一个动规状态求解:
状态定义 c n t [ i ] cnt[i] cnt[i]:以顶点i为终点的点权加和为最大值 d p [ m x i ] dp[mxi] dp[mxi]的路径的数量。
在拓扑排序过程中,在访问u的邻接点v时:

  • 如果 d p [ v ] < d p [ u ] + w [ v ] dp[v] < dp[u]+w[v] dp[v]<dp[u]+w[v],( w [ v ] w[v] w[v]是顶点v的点权)。那么要更新 d p [ v ] = d p [ u ] + w [ v ] dp[v]=dp[u]+w[v] dp[v]=dp[u]+w[v],经过顶点u再到顶点v的路径的点权加和最大,到顶点v点权加和为 d p [ v ] dp[v] dp[v]的路径数量就是到顶点u点权加为 d p [ u ] dp[u] dp[u]的路径数量,也就是 c n t [ v ] = c n t [ u ] cnt[v] = cnt[u] cnt[v]=cnt[u]
  • 如果 d p [ v ] = = d p [ u ] + w [ v ] dp[v] == dp[u]+w[v] dp[v]==dp[u]+w[v],那么 d p [ v ] dp[v] dp[v]无需更新,但到达顶点v的点权加和为 d p [ v ] dp[v] dp[v]的路径增多了,增加了到达顶点u点权加为 d p [ u ] dp[u] dp[u]的路径数量,即 c n t [ v ] + = c n t [ u ] cnt[v] += cnt[u] cnt[v]+=cnt[u],该题路径数量需要对 X X X取模,所以增加后应该再模X,写为cnt[v] = (cnt[v]+cnt[u])%x

【题解代码】

解法1:图论 tarjan求强连通分量 缩点 拓扑排序DP
#include<bits/stdc++.h>
using namespace std;
#define N 100005
int n, m, x, dp[N], w[N], cnt[N], cntAns, dfn[N], low[N], ts, scc[N], sn, degIn[N], mxi = 1;
stack<int> stk;
bool inStk[N];
vector<int> edge[N], g[N];//edge:原图 g:缩点后的图
void tarjan(int u)
{int t;dfn[u] = low[u] = ++ts;stk.push(u);inStk[u] = true;for(int v : edge[u]){if(dfn[v] == 0){tarjan(v);low[u] = min(low[u], low[v]);}else if(inStk[v])low[u] = min(low[u], dfn[v]);}if(dfn[u] == low[u]){++sn;do{t = stk.top();stk.pop();inStk[t] = false;scc[t] = sn;w[sn]++;//连通分量sn中的顶点数,也就是缩点后顶点sn的权值w[sn]增加1 } while(t != u);}
}
void topoSort()
{queue<int> que;for(int i = 1; i <= sn; ++i){dp[i] = w[i];//dp[i]:缩点后以强连通分量i为终点的点权加和最大的路径的点权加和cnt[i] = 1;if(degIn[i] == 0)que.push(i); }while(!que.empty()){int u = que.front();que.pop();if(dp[u] > dp[mxi])mxi = u;//mxi:某个以mxi为终点的路径的点权加和最大 for(int v : g[u]){if(dp[v] < dp[u]+w[v]){dp[v] = dp[u]+w[v];cnt[v] = cnt[u];}else if(dp[v] == dp[u]+w[v])cnt[v] = (cnt[v]+cnt[u])%x;if(--degIn[v] == 0)que.push(v);}}
}
int main()
{int a, b;cin >> n >> m >> x;for(int i = 1; i <= m; ++i){cin >> a >> b;edge[a].push_back(b);}for(int i = 1; i <= n; ++i) if(dfn[i] == 0)tarjan(i);for(int u = 1; u <= n; ++u)for(int v : edge[u]) if(scc[v] != scc[u])g[scc[u]].push_back(scc[v]);for(int i = 1; i <= sn; ++i){sort(g[i].begin(), g[i].end());g[i].erase(unique(g[i].begin(), g[i].end()), g[i].end());//g[i]去重 }for(int u = 1; u <= sn; ++u)for(int v : g[u])degIn[v]++;//degIn[i]:缩点后强连通分量i的入度 topoSort();cout << dp[mxi] << '\n';for(int i = 1; i <= sn; ++i) if(dp[i] == dp[mxi])//所有以i为终点的,点权加和为dp[mxi]的路径数量加和 cntAns = (cntAns+cnt[i])%x;cout << cntAns;return 0;
}

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

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

相关文章

Android打aar包问题总结

1、moduleA 依赖 moduleB&#xff0c;将moduleA打包成aar时&#xff0c;未包含 moduleB的resources资源&#xff1b; 方法一&#xff1a;将moduleB的资源&#xff0c;手动拷贝一份到moduleA中&#xff1b; 方法二&#xff1a;使用 fat-aar 插件&#xff1b; 2、fat-aar插件使…

【网络协议】【http】http 简单介绍

【网络协议】【http】http 简单介绍 1 HTTP 头部 HTTP 是一种请求-响应协议&#xff0c;客户端向服务器发送请求&#xff0c;服务器返回响应。 1.1 HTTP 状态码 状态码是服务器返回给客户端的 三位数字代码&#xff0c;用于表示请求的执行结果。 状态码按照首位数字分类&am…

谈谈空间复杂度考量,特别是递归调用栈空间消耗?

空间复杂度考量是算法设计的核心要素之一&#xff0c;递归调用栈的消耗问题在前端领域尤为突出。 以下结合真实开发场景进行深度解析&#xff1a; 一、递归调用栈的典型问题 1. 深层次DOM遍历的陷阱 // 危险操作&#xff1a;递归遍历未知层级的DOM树 function countDOMNode…

LeetCode算法题(Go语言实现)_16

题目 给定一个二进制数组 nums 和一个整数 k&#xff0c;假设最多可以翻转 k 个 0 &#xff0c;则返回执行操作后 数组中连续 1 的最大个数 。 一、代码实现 func longestOnes(nums []int, k int) int {left, zeroCnt, maxLen : 0, 0, 0for right : 0; right < len(nums); …

【数据结构】栈 与【LeetCode】20.有效的括号详解

目录 一、栈1、栈的概念及结构2、栈的实现3、初始化栈和销毁栈4、打印栈的数据5、入栈操作---栈顶6、出栈---栈顶6.1栈是否为空6.2出栈---栈顶 7、取栈顶元素8、获取栈中有效的元素个数 二、栈的相关练习1、练习2、AC代码 个人主页&#xff0c;点这里~ 数据结构专栏&#xff0c…

攻破tensorflow,勇创最佳agent(2)---损失(loss) 准确率(accuracy)问题

实战播: 怎么判定一个模型好不好,你设置的值对不对? 需要再看几个值: 例如: model Sequential()for units in model_structure:model.add(Dense(units, activationrelu))model.add(Dropout(train_config.get(dropout_rate, 0.3)))model.add(Dense(1, activationsigmoid)) 他…

pdfh5 pdf

踩坑1&#xff1a; 渲染失败 &#xff08;1&#xff09;在vue项目中&#xff0c;读取本地的pdf文件需要放到public下static文件夹中&#xff0c;不能放在别的地方&#xff1b; &#xff08;2&#xff09;引用时&#xff0c;不能使用相对路径&#xff0c;因为使用public文件下…

6.5 模拟专题:LeetCode 38. 外观数列

1. 题目链接 LeetCode 38. 外观数列 2. 题目描述 给定一个正整数 n&#xff0c;生成外观数列的第 n 项。外观数列的定义如下&#xff1a; 第 1 项为 "1"。第 n 项是对第 n-1 项的描述。例如&#xff0c;第 2 项描述第 1 项&#xff08;"1"&#xff09;为…

什么是具身智能

具身智能&#xff08;Embodied Intelligence&#xff09;是人工智能与机器人学交叉的前沿领域&#xff0c;强调智能体通过身体与环境的动态交互实现自主学习和进化&#xff0c;其核心在于将感知、行动与认知深度融合‌。通俗地讲&#xff0c;就是机器人或者智能系统在物理环境中…

git命令使用小记(打补丁)

需求&#xff1a;需要从开发分支提取本人提交代码&#xff0c;然后合并到主分支 一、制作补丁包 mkdir -p patches for commit in $(git log commitA..commitB --author"username" --reverse --prettyformat:"%h"); do …

mapbox基础,加载popup弹出窗

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️popup 弹出窗 api1.3.1 ☘️构造函数1.…

C++11--(1)

目录 1.列表初始化 {}初始化 C98中 C11中 内置置类型和自定义类型 创建对象也适用 std::initializer_list 2.变量类型推导 auto C98 C11 decltype nullptr 3.范围for循环 4.STL中一些变化 array 1.创建和初始化 2.访问元素 ​编辑 3.修改操作 4.支持迭代器…

Promise的状态和方法是什么?

Promise 的状态和方法 1. Promise 的状态 一个 Promise 可以处于以下三种状态之一&#xff1a; - Pending&#xff08;待定&#xff09;&#xff1a;初始状态&#xff0c;表示异步操作正在进行中&#xff0c;Promise 还没有被解决或拒绝。 - Fulfilled&#xff08;已完成&…

Windows云服务器支持哪些数据库管理系统?

Windows云服务器因其良好的兼容性和企业级支持&#xff0c;广泛用于网站托管、企业管理系统、金融应用、数据分析等场景。在这些应用中&#xff0c;数据库管理系统(DBMS)起着至关重要的作用。Windows 服务器支持多种数据库&#xff0c;包括关系型数据库(SQL)和非关系型数据库(N…

MongoDB 实际工作中应用场景

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

03 相机标定图像采集

学完本文,您将获取一下技能: 1:如何提升标定质量,如选择标定板,标定图像采集的注意事项, 2:实现标定图像自动筛选的代码 3:量产场景如何通过一张图像来标定相机 为了实现良好的标定效果,以下因素在标定数据采集前必须设置得当。 标定板选择 标定板尺寸准确材料平…

GitHub美化个人主页3D图表显示配置操作

这个功能主要是用的这个开源仓库&#xff1a;https://github.com/yoshi389111/github-profile-3d-contrib 想看效果的话&#xff0c;我的个人主页&#xff1a;https://github.com/Sjj1024 开始操作 1.创建自己的github主页属性项目——跟你github用户名一致即可&#xff0c;…

buu-jarvisoj_fm-好久不见52

格式化字符串漏洞题 x等于4x等于4​​​​​​​x等于4​​​​​​​x等于4 可以知道是第11个参数&#xff0c;%11$ 定位到这个位置&#xff0c;然后%n往这个位置写入4 1.先用pwndbg调试得到偏移量 2.查看获取x的地址 3.构造ROP链&#xff0c;发送连接 from pwn import *# …

AwesomeQt分享3(含源码)

AwesomeQt 这个项目包含了多个Qt组件的使用示例&#xff0c;旨在展示Qt各种强大功能的实现方式。 源码分享 github: awesome_Qtgitee: 后续同步 项目进度 QCustomPlot曲线控件示例 支持排序和筛选的列表控件示例 支持排序和筛选的表格控件示例 属性表示例 Dock窗口示例 自绘…

ubuntu 安装 g++

文章目录 前提一、安装 g1.1 安装1.2 验证 前提 安装 tflite_support 报错 error: subprocess-exited-with-error RuntimeError: Unsupported compiler -- at least C11 support is needed!一、安装 g 1.1 安装 # 安装编译工具链&#xff08;如g&#xff09;和依赖库 sudo …