算法基础课-搜索与图论

DFS

题目链接:842. 排列数字 - AcWing题库
思路:写的很好的题解AcWing 842. 排列数字--深度优先遍历代码+注释 - AcWing

#include<bits/stdc++.h>using namespace std;
int n;
int st[10];
vector<int> a;
void dfs(){if(a.size() == n){for(int i=0;i<n;i++){cout<<a[i]<<" ";}cout<<endl;}for(int i=1;i<=n;i++){if(!st[i]){a.push_back(i);st[i] = true;dfs();a.pop_back();st[i] = false;}}
}int main()
{cin>>n;dfs();return 0;
}

也可以考虑使用c++自带的next_permutation函数直接秒了:

#include<bits/stdc++.h>
using namespace std;
vector<int> a;
int n;
int st[10];int main(){cin>>n;for(int i=0;i<n;i++) st[i] = i+1;do{for(int i=0;i<n;i++) cout<<st[i]<<" ";cout<<endl;}while(next_permutation(st,st+n));return 0;
} 

BFS

题目链接:844. 走迷宫 - AcWing题库

思路:由于bfs是一层一层扩展,所以能保证走到终点时,走过的距离最短,所以不需要取min。可以在bfs中判断一下,走到终点直接输出终点的distance。

#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int,int> PII;
int n,m;
const int N = 110;
int g[N][N];
int dist[N][N];
int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
// int st[N][N];
void bfs(int x,int y){queue<PII> q;q.push({x,y});dist[0][0] = 0;// st[x][y] = true;while(q.size()){auto t = q.front();q.pop();int x = t.x,y = t.y;for(int i=0;i<4;i++){int tx = x + dx[i];int ty = y + dy[i];if(g[tx][ty] == 1) continue;if(tx<0||tx>=n||ty<0||ty>=m) continue;// if(st[tx][ty]) continue;// st[tx][ty] = true;g[tx][ty] = 1;dist[tx][ty] = min(dist[tx][ty],dist[x][y]+1);q.push({tx,ty});// cout<<tx<<" "<<ty<<endl;}}
}
int main(){cin>>n>>m;for(int i=0;i<n;i++){for(int j=0;j<m;j++) cin>>g[i][j];}memset(dist,0x3f,sizeof dist);bfs(0,0);cout<<dist[n-1][m-1];return 0;
}

树与图的深度优先遍历

题目链接:1207. 大臣的旅费 - AcWing题库

思路:题意是求树的直径(树中两个最远结点的距离),可以随机找一个点0,走到距离0点最远的点1,再从这个点1走到距离点1最远的点2,此时点1距离点2的距离就是树的直径。

图的存储与遍历参考:B02 图的存储_哔哩哔哩_bilibili

#include<bits/stdc++.h>
#define x first 
#define y second using namespace std;
const int N = 100010;
typedef pair<int,int> PII;
vector<PII> h[N];
int dist[N];
void dfs(int u,int father,int distance){dist[u] = distance;for(auto t:h[u]){if(t.x!=father){dfs(t.x,u,distance+t.y);}}}int main(){int n ;cin>>n;for(int i=0;i<n-1;i++){int x,y,d;cin>>x>>y>>d;h[x].push_back({y,d});h[y].push_back({x,d});}dfs(1,-1,0);int u = 1;for(int i=1;i<=n;i++){if(dist[i]>dist[u]){u = i;}}dfs(u,-1,0);for(int i=1;i<=n;i++){if(dist[i]>dist[u]){u = i;}}int s = dist[u];printf("%lld\n", s * 10 + s * (s + 1ll) / 2);return 0;
}

树与图的广度优先遍历

题目链接:847. 图中点的层次 - AcWing题库

思路:h数组表示邻接表,下标表示结点编号,每个vector存储的是每个结点能到达的节点。

这个老师讲的超级好。B02 图的存储_哔哩哔哩_bilibili

#include<bits/stdc++.h>using namespace std;
const int N = 100010;
vector<int> h[N];
bool st[N];
int dist[N];
int n,m;
void bfs(int u){queue<int> q;q.push(u);st[u] = true;dist[u] = 0;while(q.size()){int t = q.front();q.pop();if(t == n){cout<<dist[t];return;}for(int i=0;i<h[t].size();i++){int ne = h[t][i];if(st[ne]) continue;st[ne] = true;q.push(ne);dist[ne] = dist[t] + 1;}}cout<<-1<<endl;return;
}
int main(){cin>>n>>m;for(int i=0;i<m;i++){int a,b;cin>>a>>b;h[a].push_back(b);}memset(dist,-1,sizeof dist);bfs(1);return 0;
}

拓扑排序

题目链接:848. 有向图的拓扑序列 - AcWing题库
思路:跟bfs有些相似,先找入度为零的点加入到队列当中,再枚举当前结点出边,减少出边元素的入度,当入度为0时加入到拓扑序列中,这里是当出队的时候加入到序列中,跟bfs更像了。

这个老师讲的可好D01 拓扑排序_哔哩哔哩_bilibili。

#include<bits/stdc++.h>using namespace std;
const int N = 100010;
vector<int> e[N],tp;
int din[N];int n,m;
bool topsort(){queue<int> q;for(int i=1;i<=n;i++){if(din[i] == 0) q.push(i);}while(q.size()){auto t = q.front();q.pop();tp.push_back(t);for(auto y : e[t]){din[y]--;if(!din[y]) q.push(y);} }return tp.size() == n;
}int main(){cin>>n>>m;for(int i=0;i<m;i++){int a,b;cin>>a>>b;e[a].push_back(b);din[b]++;}if(topsort()){for(int i = 0;i<n;i++){cout<<tp[i]<<" ";}}else cout<<-1<<endl;return 0;
}

Dijkstra

朴素版

题目链接:849. Dijkstra求最短路 I - AcWing题库
思路:采取贪心的策略,对当前能到达的路径最短的点,使用其进行更新距离操作。

D02 最短路 Dijkstra 算法_哔哩哔哩_bilibili

#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int,int> PII;
const int N = 510;
const int M = 1e5+10;
vector<PII> e[N];
int dist[N];
int n,m;
bool st[N];
void dijkstra(int s){dist[s] = 0;for(int i=1;i<n;i++){int u = 0;for(int i=1;i<=n;i++){if(!st[i]&&(dist[i]<dist[u] || u == 0)) u = i;}// cout<<u<<endl;st[u] = true;for(auto pr : e[u]){int v = pr.x, w = pr.y;if(dist[v]>dist[u]+w){dist[v] = dist[u] + w;}}}
}int main(){cin>>n>>m;for(int i=0;i<m;i++){int a,b,w;cin>>a>>b>>w;e[a].push_back({b,w});}memset(dist,0x3f,sizeof dist);dijkstra(1);if(dist[n] == 0x3f3f3f3f) cout<<-1<<endl;else cout<<dist[n]<<endl;return 0;
}

堆优化版本

题目链接:850. Dijkstra求最短路 II - AcWing题库

思路:每次选秀选出当前最小的点,朴素版需要遍历寻找,堆优化版使用优先队列维护当前没有遍历到的距离最小的点,将每次选秀的遍历替换成取队列头部元素,从而降低时间复杂度。

需要注意的是为了维护优先队列中的顺序,存储的距离为负数。

D02 最短路 Dijkstra 算法_哔哩哔哩_bilibili

#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
int n,m;
typedef pair<int,int> PII;
const int N = 150010, M = 150010;
int dist[N];
priority_queue<PII> q;
vector<PII> h[N];
bool st[N];
void dijkstra(int s){dist[s] = 0;q.push({0,s});while(q.size()){PII p = q.top();int u = p.y;q.pop();if(st[u]) continue;st[u] = true;for(auto t : h[u]){int v = t.x, w = t.y;if(dist[v]>dist[u] + w){dist[v] = dist[u] + w;  //忘记更新距离q.push({-(dist[u]+w),v});}}}
}
int main(){cin>>n>>m;for(int i=0;i<m;i++){int a,b,c;cin>>a>>b>>c;h[a].push_back({b,c});}memset(dist,0x3f,sizeof dist);dijkstra(1);if(dist[n] == 0x3f3f3f3f) cout<<-1<<endl;else cout<<dist[n]<<endl;return 0;
}

bellman-ford

spfa

Floyd

题目链接:854. Floyd求最短路 - AcWing题库

思路:D04 最短路 Floyd 算法_哔哩哔哩_bilibili

#include<bits/stdc++.h>
using namespace std;
const int N = 210,INF = 1e9;
int n,m,Q;
int d[N][N];
void floyd(){for(int k=1;k<=n;k++){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){d[i][j] = min(d[i][j],d[i][k]+d[k][j]);}}}
}
int main(){cin>>n>>m>>Q;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(i==j) d[i][j] = 0;else d[i][j] = INF;}}	while(m--){int a,b,c;cin>>a>>b>>c;d[a][b] = min(d[a][b],c);}floyd();while(Q--){int a,b;cin>>a>>b;int t = d[a][b];if(t>INF/2) cout<<"impossible"<<endl;else cout<<t<<endl;}return 0;
}

Prim

题目链接:858. Prim算法求最小生成树 - AcWing题库

思路:D07 最小生成树 Prim 算法_哔哩哔哩_bilibili

和dijkstra一样,n次循环,每次选取最近的点来更新距离。

#include<bits/stdc++.h>
using namespace std;
const int N = 510,INF = 0x3f3f3f3f;
int n,m;
int g[N][N];
int dist[N];
bool st[N];
int prim(){memset(dist,0x3f,sizeof dist);int res = 0;for(int i=0;i<n;i++){int t = -1;for(int j=1;j<=n;j++){if(!st[j]&&(t==-1||dist[t]>dist[j]))t = j;}if(i && dist[t]==INF) return INF;if(i) res += dist[t];st[t] = true;for(int j=1;j<=n;j++) dist[j] = min(dist[j],g[t][j]);}return res;
}int main(){cin>>n>>m;memset(g,0x3f,sizeof g);while(m--){int a,b,c;cin>>a>>b>>c;g[a][b] = g[b][a] = min(g[a][b],c);}int t = prim();if(t==INF) cout<<"impossible"<<endl;else cout<<t<<endl;return 0;
}

Kruskal

题目链接:859. Kruskal算法求最小生成树 - AcWing题库

思路:Kruskal算法是根据边求取最小生成树,先按边权排序,依次取权重最小的边,查看边的起点和终点是否在同一集合中(使用并查集),若不在同一集合,则将边加入到答案中,若在同一集合则继续循环。D08 最小生成树 Kruskal 算法_哔哩哔哩_bilibili

需要注意的是重载小于号的操作要记一下。

#include<bits/stdc++.h>
// #define x first
// #define y second
using namespace std;
// typedef pair<int,int> PII;
int n,m;
const int N = 1e5+10,M = 2e5+10;
struct edge{int u;int v;int w;bool operator<(const edge &t)const{return w<t.w;}
}e[M];
// vector<edge> e;
int fa[N];
int find(int x){if(x == fa[x]) return x;return fa[x] = find(fa[x]);
}
int main(){cin>>n>>m;for(int i=0;i<m;i++){int a,b,c;cin>>a>>b>>c;e[i] = {a,b,c};}int ans = 0;int cnt = 0;sort(e,e+m);for(int i=1;i<=n;i++) fa[i] = i;for(int i=0;i<m;i++){int u = e[i].u;int v = e[i].v;int w = e[i].w;if(find(u)!=find(v)){ans += w;   fa[find(u)] = find(v);cnt++;}}if(cnt == n-1) cout<<ans<<endl;else cout<<"impossible"<<endl;return 0;
}

染色法判定二分图

题目链接:860. 染色法判定二分图 - AcWing题库
思路:二分图的意思是看是否有能将所有节点分成两块,每块的节点中不能直接相连这样的情况存在。如下图中的1,4和2,3,5。根据定理:二分图中不存在奇环,我们可以由此判别一个图是否是二分图。D24 二分图判定 染色法_哔哩哔哩_bilibili

老师使用的是链式前向星存储的图结构,具体思路如下。感觉直接用邻接表存储更好想,也更简便。

#include<bits/stdc++.h>using namespace std;
int n,m;
const int N = 100010,M = 100010;
vector<int> h[N];
int color[N];
bool dfs(int u,int c){color[u] = c;for(auto t : h[u]){if(!color[t]){if(dfs(t,3-c)) return 1;}else if(color[t] == c) return 1;}return 0;
}int main(){cin>>n>>m;for(int i=0;i<m;i++){int a,b;cin>>a>>b;h[a].push_back(b);h[b].push_back(a);}bool flag = false;for(int i =1;i<=n;i++){if(!color[i]){if(dfs(i,1)){flag = 1;break;}}}if(flag) puts("No");else puts("Yes");return 0;}

匈牙利算法

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

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

相关文章

安全的通信协议HTTPS被攻击改采用什么防护方案

随着互联网的发展&#xff0c;保护用户在网上交换的敏感信息的安全性变得至关重要。HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;作为一种安全的通信协议&#xff0c;通过加密数据传输&#xff0c;保护用户的隐私和数据安全。然而&#xff0c;尽管HTTPS提…

Kafka基础 (上)

前言 各位清明 快乐呀,近期博主也是学习了一下kafka,以下是博主的一些学习笔记,希望对你有所帮助 前置知识 线程中的数据交互以及进程中的数据交互 我们知道线程之间可以使用堆空间进行数据交互的 但是如果发送方和接收方处理数据的效率差距过大,这里就会造成消息积压的问题,怎…

闪站侠洗护管理系统,洗衣洗鞋小程序软件定制,干洗连锁店软件系统搭建;

闪站侠洗护管理系统&#xff0c;洗衣洗鞋小程序软件定制&#xff0c;干洗连锁店软件系统搭建&#xff1b; 为了让每一个洗衣洗鞋工厂与门店的连接更加高效便捷&#xff0c;送洗流程更加简单轻松&#xff0c;拽牛科技倾心打造洗衣洗鞋管理软件。我们的目标是通过高效和优质的服务…

Prometheus+grafana环境搭建Docker服务(docker+二进制两种方式安装)(八)

由于所有组件写一篇幅过长&#xff0c;所以每个组件分一篇方便查看&#xff0c;前七篇链接如下 Prometheusgrafana环境搭建方法及流程两种方式(docker和源码包)(一)-CSDN博客 Prometheusgrafana环境搭建rabbitmq(docker二进制两种方式安装)(二)-CSDN博客 Prometheusgrafana环…

「 典型安全漏洞系列 」12.OAuth 2.0身份验证漏洞

在浏览网页时&#xff0c;你肯定会遇到允许你使用社交媒体帐户登录的网站。此功能一般是使用流行的OAuth 2.0框架构建的。本文主要介绍如何识别和利用OAuth 2.0身份验证机制中发现的一些关键漏洞。 1. OAuth产生背景 为了更好的理解OAuth&#xff0c;我们假设有如下场景&#…

【vite】-【vite介绍】-【vite的基础应用】-【vite的高级应用】-【

目录 vite介绍vite的基础应用vite创建项目vite创建vue3项目vite创建vue2项目vite创建react项目 vite中使用css的各种功能vite中使用tsvite中处理静态资源的方法vite集成eslint和prettiervite中的env环境变量 vite的高级应用 vite介绍 一、特点&#xff1a; 开发时效率极高开箱…

深入浅出 -- 系统架构之负载均衡Nginx动静分离

一、Nginx动静分离 动静分离应该是听的次数较多的性能优化方案&#xff0c;那先思考一个问题&#xff1a;为什么需要做动静分离呢&#xff1f;它带来的好处是什么&#xff1f; 其实这个问题也并不难回答&#xff0c;当你搞懂了网站的本质后&#xff0c;自然就理解了动静分离的重…

【微信小程序】【小程序样式加载不出来】

微信小程序配置sass 第一步&#xff1a;找配置文件 在项目中找到 project.config.json文件&#xff0c;在setting属性中添加 useCompilerPlugins属性&#xff0c;值为sass即可&#xff0c;若是 less,将数组里面的值改为less即可 "useCompilerPlugins": ["sas…

软考116-上午题-【计算机网络】-LINUX命令

一、真题 真题1&#xff1a; 真题2&#xff1a; 权限通常分为三类&#xff1a; 读&#xff08;r&#xff09;&#xff1a;允许读取文件内容或列出目录内容。写&#xff08;w&#xff09;&#xff1a;允许修改文件内容或在目录中创建/删除文件。执行&#xff08;x&#xff09;&…

基于YOLOv8的铁路工人安全作业检测系统

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文摘要&#xff1a;基于YOLOv8的铁路工人安全作业检测系统&#xff0c;属于小目标检测范畴&#xff0c;并阐述了整个数据制作和训练可视化过程&#xff0c; 博主简介 AI小怪兽&#xff0c;YOLO骨灰级玩家&#xff0c;1&#xff0…

After Effects 2024:创意无界,想象成真mac/win版

在数字艺术飞速发展的今天&#xff0c;After Effects 2024已经站在了视觉特效和动态图形设计的最前沿。这款软件不仅继承了之前版本的强大功能&#xff0c;更在细节和效率上进行了全方位的优化和升级。 After Effects 2024软件获取 After Effects 2024为用户提供了更加丰富的特…

摄影杂记一

摄影小白&#xff0c;最近买了一台微单&#xff0c;型号是佳能R10&#xff0c;加上18-150套机镜头和佳能RF 50 F1.8定焦镜头。开始学习摄影。 PS&#xff1a;摄影穷三代&#xff0c;单反毁一生。嘿嘿。 一、分镜头拍摄四步提升法 B站&#xff1a;六斤 拍视频三件事&#xff1…