2025.8.6 图论(1)Solution

割点

学习资料,在 csdn 或洛谷上看都行。是模板题题解(之一)。

T1:Atserckcn与逃离恐怖老师。

题意简述:从一个图中选定一个点,使得删除这个点后图不连通。求该点编号,无解输出 -1。图不一定联通。

那么本题显然就是割点模板题,在模板题代码中稍微修改即可。

最小生成树

最小生成树一般有两种算法:Kruskal and Prim。

kruskal

基本思想:采取贪心的思想,对边按边权为关键字,从小到大排序。遍历所有边,用并查集维护边连接的两个点。如果两个点之前并不在一个连通块中,那么此边就是最小生成树中的其中一个边。反之跳过。直至选择了 n−1n-1n1 条边,变成了一棵树。

实例代码:

sort(edge+1,edge+m+1,cmp);//对边进行排序for(int i=1;i<=m;i++)//遍历每条边{if(!Union(edge[i].u,edge[i].v))//检查u,v是否在同一连通块{//是的话,选取这条边。ans+=edge[i].w;cnt++;}if(cnt>=n-1){break;}}
Prim

思想:也是运用贪心的思想,不过不同于 Kruskal 的是,Kruskal 是按照边进行贪心选取,而 Prim 是基于点。

  • 一开始先将点 111 加入生成树。

  • 维护一个数组,表示每个点到目前最小生成树的距离,执行 n−1n-1n1 次,每次选取最近的一个点加入生成树,并更新距离。

for(re int i=2;i<=n;++i)dis[i]=inf;for(re int i=head[1];i;i=e[i].next)dis[e[i].v]=min(dis[e[i].v],e[i].w);//更新while(++tot<n)//再次加入n-1个点{int minn=inf;vis[now]=1;for(int i=1;i<=n;++i){if(!vis[i]&&minn>dis[i]){minn=dis[i];now=i;}}ans+=minn;//更新disfor(int i=head[now];i;i=e[i].next){int v=e[i].v;if(dis[v]>e[i].w&&!vis[v])dis[v]=e[i].w;}}return ans;

从TJ区搞过来的,大家可以自行试试。

T2:Atserckcn 与选取隧道

原题:YZOJ P1038 – 隧道

思路:

  • 因为道路/隧道需要连接每个岛,并且它们的建设数量要最小,所以不难看出总结果一定是一棵树。
  • 岛上的居民喜欢隧道,而不是桥梁,那么就多选隧道。
  • 隧道对答案的贡献是 000
  • 桥梁对答案的贡献是 111
  • 可以将每条隧道的权值设为 000,桥梁的权值设为 111,用 Kruskal 或 Prim 实现

实现代码:(kruskal)

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5,K=1.2e4+5,M=K;
int n,k,m,fa[N],cnt_e,ans,cnt;
struct E{int from,to,w;
}e[K+M];
bool operator < (const E &x,const E &y)//按照权值小到大排序
{return x.w<y.w;
}
int findfa(int x)//并查集部分
{return fa[x]==x?x:fa[x]=findfa(fa[x]);
}
void Union(int x,int y)
{fa[findfa(x)]=findfa(y);return;
}
void kruskal()
{sort(e+1,e+cnt_e+1);for(int i=1;i<=cnt_e;++i){int u=e[i].from,v=e[i].to,w=e[i].w;if(findfa(u)!=findfa(v)){Union(u,v);++cnt;ans+=w;if(cnt>=n-1)break;}}return;
}
int main(){ios::sync_with_stdio(0);cin>>n>>k>>m;for(int i=1;i<=n;++i)fa[i]=i;for(int i=1;i<=k;++i){++cnt_e;cin>>e[cnt_e].from>>e[cnt_e].to;e[cnt_e].w=0;}for(int i=1;i<=m;++i){++cnt_e;cin>>e[cnt_e].from>>e[cnt_e].to;e[cnt_e].w=1;}kruskal();cout<<ans<<'\n';return 0;
}

缩点

前置知识点:强连通分量。学习资料。

原题:YZOJ P1332 – Love

对于本题,O(n2)O(n^2)O(n2) 的枚举肯定超时,考虑优化。

将粉丝视为点,uuu 崇拜 vvv 则当为一条连接 (u,v)(u,v)(u,v) 的有向边。

  • 如果某个连通块里的所有人都互相崇拜,那么这一大块的人目前都是最无脑粉丝
  • 考虑运用强连通分量,将上述的所有互相崇拜的联通块视作一个点,在新图上操作。
  • 接下来看出度,如果这个点没有出度,说明他们没有崇拜的人,都可能是最佳无脑粉丝
  • 但是如果有两个以上这样的连通块,最佳无脑粉丝就一个都不是。

实例代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5,M=1e6+5;
int n,m,ehead[N],cnt_e,dfn[N],low[N],idx,tot,belong[N],deg[N],siz[N],ans,cntans;
stack<int> st;
bool inst[N];
struct E{int to,pre;
}e[M];
void adde(int from,int to)
{e[++cnt_e].to=to;e[cnt_e].pre=ehead[from];ehead[from]=cnt_e;return;
}
void dfs(int u)
{low[u]=dfn[u]=++idx;inst[u]=1;st.push(u);for(int i=ehead[u];i;i=e[i].pre){int v=e[i].to;if(!dfn[v]){dfs(v);low[u]=min(low[u],low[v]);}elseif(inst[v])low[u]=min(low[u],dfn[v]);}if(low[u]==dfn[u]){vector<int> vec;vec.clear();++tot;while(1){int t=st.top();st.pop();vec.push_back(t);inst[t]=0;if(t==u)break;}for(int i=0;i<(int)vec.size();++i)belong[vec[i]]=tot;for(int i=0;i<(int)vec.size();++i){int u=vec[i];for(int j=ehead[u];j;j=e[j].pre){int v=e[j].to;if(belong[v]!=tot)++deg[tot];}}siz[tot]=vec.size();
//		cout<<tot<<":\n";
//		for(int i=0;i<(int)vec.size();++i)
//			cout<<vec[i]<<' ';
//		cout<<'\n';vec.clear();}return;
}
int main(){ios::sync_with_stdio(0);cin>>n>>m;for(int i=1,u,v;i<=m;++i){cin>>u>>v;adde(u,v);}for(int i=1;i<=n;++i)if(!dfn[i])dfs(i);
//	for(int i=1;i<=n;++i)
//		cout<<belong[i]<<' ';
//	cout<<'\n';for(int i=1;i<=tot;++i){if(!deg[i]){ans+=siz[i];++cntans;}}if(cntans>1){cout<<"0\n";return 0;}cout<<ans<<'\n';return 0;
}

LCA

学习资料。

对于本题,由于在一棵树上,两点的距离就是两点 a,ba,ba,b 到根节点(假定为 111)的距离减去两倍根节点到 LCA(a,b)LCA(a,b)LCA(a,b) 的距离,不懂画个图就懂。

示例代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,q,cnt_e,ehead[N],dis[N],fa[N][25],dep[N];
struct E{int to,w,pre;
}e[N<<1];
void adde(int from,int to,int w)
{e[++cnt_e].to=to;e[cnt_e].w=w;e[cnt_e].pre=ehead[from];ehead[from]=cnt_e;return;
}
void dfs(int u,int u_f)
{fa[u][0]=u_f;for(int i=1;i<=20;++i)fa[u][i]=fa[fa[u][i-1]][i-1];for(int i=ehead[u];i;i=e[i].pre){int v=e[i].to,w=e[i].w;if(v==u_f)continue;dis[v]=dis[u]+w;dep[v]=dep[u]+1;dfs(v,u);}return;
}
int getlca(int x,int y)
{if(dep[x]<dep[y])swap(x,y);//dep[x]>=dep[y]for(int i=20;i>=0;--i)//倍增{if(dep[x]-(1<<i)>=dep[y])x=fa[x][i];}if(x==y)return x;for(int i=20;i>=0;--i){if(fa[x][i]!=fa[y][i]){x=fa[x][i];y=fa[y][i];}}return fa[x][0];
}
int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n>>q;for(int i=1,u,v,w;i<n;++i){cin>>u>>v>>w;adde(u,v,w);adde(v,u,w);}dfs(1,1);while(q--){int x,y,lcaxy;cin>>x>>y;lcaxy=getlca(x,y);cout<<dis[x]+dis[y]-2*dis[lcaxy]<<'\n';}return 0;
}

题目讲解完毕,看一些其他算法:

单源最短路——Floyd 算法

本质是个 dp,用 fk,i,jf_{k,i,j}fk,i,j 表示只经过前 kkk 个点,i,ji,ji,j 之间的最短路径。

每次转移有两种选择:

  • 经过第 kkk 个点,fk,i,j=fk−1,i,k+fk−1,k,jf_{k,i,j}=f_{k-1,i,k}+f_{k-1,k,j}fk,i,j=fk1,i,k+fk1,k,j
  • 不经过,fk,i,j=fk−1,i,jf_{k,i,j}=f_{k-1,i,j}fk,i,j=fk1,i,j

注意到 fk,i,jf_{k,i,j}fk,i,j 的转移只跟 fk−1,i,jf_{k-1,i,j}fk1,i,j 有关系,所以可以省去 kkk 这一维,运用状态的继承性。

核心代码:

for(int k=1;k<=n;++k)for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
问题:

那么 Floyd 可不可以判断负环呢?如果可以,怎么判断?如果不行,又为什么?

欧拉道路

学习资料。

不过有点冷门了,考试一般不会考……

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

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

相关文章

OpenBayes 教程上新丨一键部署 gpt-oss-20b,实测开源推理模型新 SOTA,性能直逼 o3‑mini

时隔 6 年&#xff0c;自 GPT-2 以来&#xff0c;OpenAI 终于再度发布开源大模型——gpt-oss-120b 和 gpt-oss-20b&#xff0c;前者以千亿级参数专为复杂推理与知识密集型场景设计&#xff0c;后者则更适合低延迟、本地或专业垂直领域使用&#xff0c;可在消费级硬件&#xff0…

nlp-句法分析

目录 一、句法概述 1、成分语法理论概述 &#xff08;1&#xff09;分析过程 &#xff08;2&#xff09;缺点 2、依存语法理论概述 &#xff08;1&#xff09;依存关系、配价模式 &#xff08;2&#xff09;分类 &#xff08;3&#xff09;优势&#xf…

linux磁盘加密

在Linux中&#xff0c;磁盘加密是一种保护数据不被未授权访问的方法。有多种工具和策略可以实现磁盘加密&#xff0c;包括使用Linux内核的内置功能&#xff0c;如dm-crypt&#xff0c;以及使用更高级的解决方案&#xff0c;如LUKS&#xff08;Linux Unified Key Setup&#xff…

大数据架构演变之路

目录 一、各阶段的架构简介 二、各个架构的详细解释 1. 传统离线架构 2.1. Lambda架构-离线数仓分析实时链路分析 2.2. Lambda架构-离线数仓实时数仓 3. Kappa/流批一体架构 4. 湖仓一体架构 三、总结 一、各阶段的架构简介 技术架构 核心驱动(核心需求) ‌关键技术 …

STM32 HAL库驱动0.96寸OLED屏幕

STM32 HAL库驱动0.96寸OLED屏幕 项目概述 本项目使用STM32 HAL库为0.96寸OLED屏幕编写驱动程序。OLED屏幕通过I2C接口与STM32单片机通信&#xff0c;实现文本、数字和图形的显示功能。 项目仓库地址&#xff1a;STM32_Sensor_Drives 硬件连接 OLED屏幕通过I2C接口与STM32连…

横向越权:修改参数访问不属于自己的数据

一、什么是横向越权定义 横向越权&#xff08;Horizontal Privilege Escalation&#xff09;是指 同一权限级别的用户&#xff0c;通过篡改请求参数或资源标识&#xff0c;访问本不属于自己的数据或功能。例子 假设一个在线商城&#xff0c;用户 A 访问订单详情的 URL&#xff…

攻击实验(ARP欺骗、MAC洪范、TCP SYN Flood攻击、DNS欺骗、DHCP饿死)

实验一 ARP欺骗一、拓扑二、实验准备、1.设置终端漏洞靶机集合选择需要的数量和镜像打开设备上的驱动精灵安装网卡安装成功后查看IP地址、网关信息等。三、实验步骤1.实验原理中间人&#xff08;攻击者&#xff09;在终端与网关之间持续发送伪造的 ARP 应答包&#xff0c;双向欺…

VSCode 禁用更新检查的方法

通过设置菜单禁用 这是最直接和推荐的方法&#xff0c;可以永久禁用自动更新&#xff1a; 打开 VSCode。点击左下角的齿轮图标&#xff0c;然后选择“设置”。或者通过菜单栏“文件” > “首选项” > “设置”进入。在顶部的搜索框中输入“update”。找到“Update: Mode”…

Flutter - 应用启动/路由管理

一、应用入口1. 初始化 Flutter 底层绑定 &#xff0c;运行 App。import package:flutter/material.dart; import package:flutter_base/Application.dart;void main() {// 确保绑定初始化WidgetsFlutterBinding.ensureInitialized();// App初始化Application.init(); }2. 注册…

MySQL 数据操作全流程:创建、读取、更新与删除实战

MySQL系列 文章目录MySQL系列前言一、Create(创建)并插入数据1.1 单行数据 全列插入1.2 多行数据 指定列插入1.3 插入冲突时同步更新1.4 冲突时替换二、Retireve读取数据2.1 全列查询2.2 查询指定列2.3 查询字段为表达式2.4 结果去重 DISTINCT2.5 where条件筛选2.6 order by语…

SQL约束:数据完整性的守护者

在SQL中&#xff0c;约束&#xff08;Constraints&#xff09; 是作用于数据库表字段上的规则&#xff0c;用于强制保证数据的完整性、准确性和一致性。当插入、更新或删除数据时&#xff0c;约束会自动验证操作是否符合规则&#xff0c;若违反则拒绝执行。 以下是SQL中常见的约…

Springboot-vue 地图展现

在很多社区管理系统中&#xff0c;地图展示功能是一个重要的模块&#xff0c;它能直观地呈现小区的地理位置分布。本文将详细梳理从前端触发请求到地图上展示小区数据的完整流程&#xff0c;帮助大家理解前后端协同工作的具体细节。一、前端触发&#xff1a;页面加载与地图初始…

Vue 3 登录组件

Login.vue 组件详细分析整体架构 Vue 3 登录组件&#xff0c;采用 Composition API Element Plus UI 库&#xff0c;实现了完整的用户认证界面。 模板结构分析 1. 容器布局 <div class"login-container"><el-card class"login-card"><!-- …

小结: getSpringFactoriesInstances从 `spring.factories` 文件中加载和实例化指定类型的类

getSpringFactoriesInstances 方法工作原理 getSpringFactoriesInstances 是 Spring Boot 框架中的一个核心方法&#xff0c;用于从 spring.factories 文件中加载和实例化指定类型的类。这是 Spring Boot 实现自动配置和插件化扩展的关键机制。 1. 基本功能 该方法的主要作用是…

selenium SessionNotCreatedException问题解决办法

在上周有一台服务器重启之后&#xff0c;Chrome浏览器也自动升了级&#xff0c;原本能够正常使用的自动化办公程序突然没法用了&#xff0c;出现了下面的报错提示。codes/addCancelBdld.py:980: DeprecationWarning: use options instead of chrome_optionsdriver webdriver.C…

SOAP HTTP Binding

SOAP HTTP Binding 引言 SOAP(Simple Object Access Protocol)是一种轻量级、简单的协议,用于在网络上交换结构化信息。它广泛应用于Web服务中,用于实现不同系统和应用程序之间的通信。SOAP HTTP Binding是SOAP协议的一种实现方式,它允许使用HTTP协议来传输SOAP消息。本…

GPT-5免费使用教程(国内可访问)

GPT-5来了&#xff0c;压力给到各大AI模型厂商&#xff1f; 北京时间2025年8月7日&#xff0c;OpenAI 推出两款开源模型 gpt-oss-120b / 20b&#xff0c;性能逼近 o4-mini/o3-mini&#xff0c;一时间火爆AI圈&#xff1b;但这好像只是一道开胃小菜&#xff0c;在北京时间2025年…

内存作假常见方案可行性分析

内存作假通常修改所涉及到的几个文件&#xff1a;M sys/frameworks/base/core/java/android/app/ActivityManager.javaM sys/frameworks/base/core/jni/android_os_Debug.cppM sys/frameworks/base/core/jni/android_util_Process.cppM sys/frameworks/base/services/core/java…

C#(vs2015)利用unity实现弯管机仿真

以下是基于 Visual Studio 2015 和 Unity 实现弯管机仿真的完整技术流程&#xff0c;结合工业仿真开发的最佳实践整理而成&#xff0c;涵盖建模、通信、运动控制和交互逻辑等核心模块&#xff1a;---一、环境配置与基础框架搭建 1. Unity 与 VS2015 联动 - 安装 [Visual Studio…

华为USG防火墙双机,但ISP只给了1个IP, 怎么办?

华为USG防火墙双机&#xff0c;但ISP只给了1个IP&#xff0c; 怎么办&#xff1f; 华为USG双机使用VRRP&#xff0c;需要3个Ip 本次联通只给了 100.1.1.0/30 这一个互联段 联通侧用了100.1.1.1&#xff0c; 我们这一侧只有100.1.1.2 怎么办&#xff1f; 找联通多要几个Ip&…