当前位置: 首页 > ds >正文

图论(邻接表)DFS

竞赛中心 - 蓝桥云课

#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int A=1e5+1;
typedef pair<int,int>p;
map<p,int>st;
vector<p>edge[A];
int a[A];
int result=0;
bool dfs(int s,int u,int father,int v,int sum)
{if(u==v){st[{s,v}]=sum;st[{v,s}]=sum;return true;}for(size_t i=0;i<edge[u].size();i++){int son=edge[u][i].first;if(son==father){continue;}if(dfs(s,son,u,v,sum+edge[u][i].second)){return true;}}return false;
}
signed main()
{// 请在此输入您的代码int N,K,u,v,t;cin>>N>>K;for(int i=0;i<N-1;i++){cin>>u>>v>>t;edge[u].push_back({v,t});edge[v].push_back({u,t});}for(int i=0;i<K;i++){cin>>a[i];}for(int i=0;i<K-1;i++){dfs(a[i],a[i],-1,a[i+1],0);result+=st[{a[i],a[i+1]}];}for(int i=0;i<K;i++){int result1=result;if(i==0){result1-=st[{a[i],a[i+1]}];}else if(i==K-1){result1-=st[{a[i-1],a[i]}];}else{result1-=st[{a[i-1],a[i]}];result1-=st[{a[i],a[i+1]}];dfs(a[i-1],a[i-1],-1,a[i+1],0);result1+=st[{a[i-1],a[i+1]}];}cout<<result1<<" ";}return 0;
}

构造邻接表,由于题意中存在边权值时间,定义邻接表为pair类型。通过typedef关键字重命名了pair类型为p。

根据题目要求暴力搜索题目要求的路线,得到原路线的时间总和。

dfs函数:

bool dfs(int s,int u,int father,int v,int sum)
{if(u==v){st[{s,v}]=sum;st[{v,s}]=sum;return true;}for(size_t i=0;i<edge[u].size();i++){int son=edge[u][i].first;if(son==father){continue;}if(dfs(s,son,u,v,sum+edge[u][i].second)){return true;}}return false;
}

s和v分别代表路线的起点和终点,u代表当前节点,father代表当前节点的父节点(为了防止走回头路),sum表示起点到当前节点的路径和。

终止条件:当当前节点到达终点,st数组存储路径和。

递归逻辑:从当前节点向后遍历,edge[u]这个邻接表存储了当前节点连接的子节点,遍历每一个子节点(注意:i的类型要为size_t,要与edge[u].size()一致)。当前节点的子节点为edge[u][i].first(表示u节点出发的第i条边,first表示节点值,second表示边权),如果发现子节点等于父节点,走回头路了,就结束这次循环,换下一个节点,如果子节点可以到达目标终点,则向上返回true,如果所有条件都没有满足,则返回false。

问题解决思路:

for(int i=0;i<K-1;i++){dfs(a[i],a[i],-1,a[i+1],0);result+=st[{a[i],a[i+1]}];}for(int i=0;i<K;i++){int result1=result;if(i==0){result1-=st[{a[i],a[i+1]}];}else if(i==K-1){result1-=st[{a[i-1],a[i]}];}else{result1-=st[{a[i-1],a[i]}];result1-=st[{a[i],a[i+1]}];dfs(a[i-1],a[i-1],-1,a[i+1],0);result1+=st[{a[i-1],a[i+1]}];}cout<<result1<<" ";}

先暴力搜索邻接表(a中存储的是节点值),得到每一步的路径值,将他们累加起来得到目标路径总和。得到最终结果分为三种情况,第一种情况为删掉的节点是第一个节点,就将第一个节点和第二个节点的路径减去就解决了。第二种情况是删掉的节点是最后一个节点,就将最后一个节点和倒数第二个节点的路径减去就解决了。第三种情况为其他,减去左右两节点的路径和后还要加上左节点到右节点的路径和,这个路径和并没有搜索过,所以要再进行一遍搜索。

http://www.xdnf.cn/news/17313.html

相关文章:

  • SpringBoot 接入SSE实现消息实时推送的优点,原理以及实现
  • 【Linux系统】进程间通信:命名管道
  • 生成模型实战 | Transformer详解与实现
  • 分布式光伏气象站:安装与维护
  • 人大金仓数据库逻辑备份与恢复命令
  • 基于模式识别的订单簿大单自动化处理系统
  • Git 分支迁移完整指南(结合分支图分析)
  • JavaWeb(04)
  • 每日五个pyecharts可视化图表-bars(5)
  • SQL的条件查询
  • PDF注释的加载和保存的实现
  • jspdf或react-to-pdf等pdf报错解决办法
  • QT自定义控件
  • 学习日志29 python
  • 微信小程序多媒体功能实现
  • 大型音频语言模型论文总结
  • 使用Nginx部署前后端分离项目
  • 0806线程
  • MCU程序段的分类
  • http请求结构体解析
  • 【注意】HCIE-Datacom华为数通考试,第四季度将变题!
  • 时隔六年!OpenAI 首发 GPT-OSS 120B / 20B 开源模型:性能、安全与授权细节全解
  • Spring Boot部门管理系统:查询、删除、新增实战
  • 嵌入式处理器指令系统:精简指令集RISC与复杂指令集CISC的简介,及区别
  • 数据结构学习(days04)
  • Node.js- express的基本使用
  • 嵌入式学习---在 Linux 下的 C 语言学习 Day9
  • 《第五篇》基于RapidOCR的图片和PDF文档加载器实现详解
  • 基于单片机GD32E103的HID按键问题分析
  • 日常反思总结