信息学奥赛一本通 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.rhkb.cn/news/42741.html

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

相关文章

如何在 Postman 中正确设置 Session 以维持用户状态?

在 Postman 里面设置有 session 的请求。如果你还不知道什么是 session&#xff0c;那么请看这里—— session 是一种记录客户端和服务器之间状态的机制&#xff0c;用于保持用户的登录状态或者其他数据&#xff0c;从而让用户在不同页面之间保持一致的体验。 Postman 设置带 …

免费使用!OpenAI 全量开放 GPT-4o 图像生成能力!

2025年3月26日&#xff0c;OpenAI正式推出GPT-4o原生图像生成功能&#xff0c;这一更新不仅标志着多模态AI技术的重大突破&#xff0c;更引发了全球AI厂商的激烈竞争。从免费用户到企业开发者&#xff0c;从创意设计到科学可视化&#xff0c;GPT-4o正在重塑图像生成的边界。本文…

【JavaScript】八、对象

文章目录 1、对象的声明2、对象的使用3、对象中的方法4、遍历对象5、内置对象Math 1、对象的声明 一种数据类型&#xff0c;使用typeof查看类型&#xff0c;结果是object可以详细的描述描述某个事物 声明语法&#xff1a; // 多用花括号形式声明 // 比如声明一个person对象 …

C++指针(五)完结篇

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 前言 相关文章&#xff1a;C指针&#xff08;一&#xff09;、C指针&#xff08;二&#xff09;、C指针&#xff08;三&#xff09;、C指针&#xff08;四&#xff09;万字图文详解&#xff01; 本篇博客是介…

DataGear 企业版 1.4.0 发布,数据可视化分析平台

DataGear 企业版 1.4.0 已发布&#xff0c;欢迎体验&#xff01; http://datagear.tech/pro/ 企业版 1.4.0 看板可视编辑模式新增了插入看板表单/面板布局、编辑图表联动、复制/粘贴、撤销/恢复等功能&#xff0c;具体更新内容如下&#xff1a; 新增&#xff1a;看板可视编辑…

windows第十八章 菜单、工具栏、状态栏

文章目录 创建框架窗口菜单菜单的风格通过资源创建菜单菜单的各种使用通过代码创建菜单在鼠标位置右键弹出菜单 CMenu常用函数介绍工具栏方式一&#xff0c;从资源创建工具栏方式二&#xff0c;代码创建 状态栏状态栏基础创建状态栏 创建框架窗口 手动创建一个空项目&#xff…

局域网共享失败?打印机/文件夹共享工具

很多时候&#xff0c;在办公或家庭环境中&#xff0c;我们需要进行打印机和文件夹的共享&#xff0c;以便更高效地协作和处理文件。然而&#xff0c;寻找对应版本的共享设置或是不想花费太多时间去进行复杂的电脑设置&#xff0c;总是让人感到头疼。今天&#xff0c;我要向大家…

C++中使用CopyFromRecordset将记录集拷贝到excel中时,如果记录集为0个,函数崩溃,是什么原因

文章目录 原因分析解决方案1. 检查记录集是否为空2. 安全调用COM方法3.进行异常捕获4. 替代方案&#xff1a;手动处理空数据 总结 在C中使用CopyFromRecordset将空记录集&#xff08;0条记录&#xff09;复制到Excel时崩溃的原因及解决方法如下&#xff1a; 原因分析 空记录集…

torchvision中数据集的使用

1、torchvision及其数据集的介绍 1.1 torchvision介绍 torchvision 是 PyTorch 的一个官方库&#xff0c;专门用于计算机视觉任务。它提供了以下核心功能&#xff1a; 预训练模型&#xff1a;如 ResNet、VGG、EfficientNet 等。数据集&#xff1a;内置常用视觉数据集&#xf…

d2025328

一、sql-判断三角形 610. 判断三角形 - 力扣&#xff08;LeetCode&#xff09; 用一下if加上判断条件 select x,y,z,if(xy > z and xz > y and yz > x and x-y < z and x-z < y and y-z < x,Yes,No) as triangle from Triangle 二、按照分类统计薪水 190…

C++20新特性:std::assume_aligned详解

文章目录 一、概述二、函数定义与语法三、使用方法与注意事项1. 使用方法2. 注意事项 四、性能优化原理五、实际应用场景六、编译器支持情况七、总结 一、概述 C20引入了std::assume_aligned&#xff0c;这是一个非常实用的特性&#xff0c;用于告知编译器某个指针所指向的对象…

洛谷P1706 全排列题解

P1706 全排列问题 题目描述 按照字典序输出自然数 1 1 1 到 n n n 所有不重复的排列&#xff0c;即 n n n 的全排列&#xff0c;要求所产生的任一数字序列中不允许出现重复的数字。 输入格式 一个整数 n n n。 输出格式 由 1 ∼ n 1 \sim n 1∼n 组成的所有不重复的…

yum install 报错(CentOS换源):

yum instally yum utils device mapper persistent-data lvm2 报错&#xff1a; 排查错误原因&#xff1a;centos7 系统停止维护了 解决方案&#xff1a;换源&#xff08;更换操作系统&#xff09; //1.备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-…

C语言学习笔记(抱佛脚版)

毕业一年&#xff0c;发现记性是真的差&#xff0c;每次想起之前的知识总是想不全&#xff0c;看别人写的资料也懵懵懂懂。于是我索性自己再学一遍&#xff0c;并且记录一下。希望对你们也有所帮助。 正片开始&#xff01; 前面的什么if for都不难理解&#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)) 他…

Docker-Volume数据卷详讲

Docker数据卷-Volume 一&#xff1a;Volume是什么&#xff0c;用来做什么的 当删除docker容器时&#xff0c;容器内部的文件就会跟随容器所销毁&#xff0c;在生产环境中我们需要将数据持久化保存&#xff0c;就催生了将容器内部的数据保存在宿主机的需求&#xff0c;volume …

使用Selenium和lxml库搜房网爬取某地区房屋信息(python、pycharm爬虫)

一、地址&#xff1a; url "https://zb.newhouse.fang.com/house/s/b91" # 第一页的 URL 但是这个爬虫我不知道为啥总是翻不了页数&#xff0c;请帮忙修改一下~ 二、用到的知识点以及代码详解&#xff1a; 这段代码是一个使用Selenium和lxml库实现的网页爬虫&a…

ai画图comfyUI 精准定位gligen。允许指定图像中多个对象的位置和大小

基础功能下&#xff0c;outpainting是内容填充&#xff0c;拉近拉远镜头&#xff0c;自动填充旁边物体。嵌入模型也需要单独下载&#xff0c;演示完示例后推荐模型站有更直观效果介绍和用法。选中精确定位。看一眼坐标&#xff0c;直接默认出一张图。然后修改定位&#xff0c;和…

如何自动化同义词并使用我们的 Synonyms API 进行上传

作者&#xff1a;来自 Elastic Andre Luiz 了解如何使用 LLM 来自动识别和生成同义词&#xff0c; 使术语可以通过程序方式加载到 Elasticsearch 同义词 API 中。 提高搜索结果的质量对于提供高效的用户体验至关重要。优化搜索的一种方法是通过同义词自动扩展查询词。这样可以更…

boost.asio

as&#xff08;async&#xff09;:异步 同步io&#xff1a; reactor (非阻塞)&#xff08;需要注册一次&#xff0c;在等待消息时可以干别的事&#xff09; 阻塞io网络模型 接口&#xff1a;read\accept\connect\write 接口返回时&#xff0c;io完成 异步…