「Day 3—深度优先搜索 & 广度优先搜索」
1.CSP考前2.「Day 1—递归问题」3.「Day 2—贪心问题&分治&前缀和」
4.「Day 3—深度优先搜索 & 广度优先搜索」
5.「Day 4—图的存储 & 图上搜索」6.「Day 5—最短路径」7.「Day 6—单调栈 & 单调队列 & 并查集」8.「Day 7—离散化 & 树状数组 & 线段树」9.「Day 8—最小生成树之Kruskal & Prim」10.「Day 9 & 10—DP问题」11.「Day 11 & 12 & 13 & 14—杂项」12.「2024 - 暑假 - Day-1 提高笔记-割点(割边)」13.「2024 - 暑假 - Day-2 提高笔记-字典树」14.【基础知识】15.「2024 - 暑假 - Day-3 提高笔记-ST表 & RMQ」16.「2024 - 暑假 - Day-4 提高笔记-LCA最近公共祖先」17.「2025 - 寒假 - Day-2 提高笔记-反悔贪心」深度优先搜索
定义
简单来说就是,一条路走到死,不行的话就回溯,继续一条路走到死,直到抵达目标点。
习题
P2052 [NOI2011] 道路修建
思路
首先,看题目对于花费的定义,道路的长度*道路两端国家数的差值的绝对值,观察一下这个应该怎么计算,我们很明显能想到树子树大小,于是我们只要知道其中一个的子树大小
代码
#include<iostream>
#include<queue>
#include<cmath>
#include<cstring>
using namespace std;
#define int long long
struct node{
int to,next,len;
}e[2 * 1000005];
int h[1000005];
int tot = 0;
inline void adge(int x,int y,int len){
e[++ tot] = (node){y,h[x],len};
h[x] = tot;
return;
}
int n,m,ans=0,maxx=-1;
int size[1000005];
void dfs(int x,int f){
size[x] = 1;
for(int i = h[x];i != -1;i = e[i].next){
int v = e[i].to;
if(v != f){
dfs(v,x);
size[x] += size[v];
ans += e[i].len * abs(n - 2 * size[v]);
}
}
}
signed main(){
memset(h,-1,sizeof(h));
cin >> n;
for(int i = 1;i < n;i ++){
int u,v,w;
cin >> u >> v >> w;
adge(u,v,w);
adge(v,u,w);
}
dfs(1,0);
cout << ans << "\n";
return 0;
}
P1434 [SHOI2002] 滑雪
思路
这个题说实话挺水的,就正常
代码
#include<iostream>
using namespace std;
int n,m;
int mp[105][105];
int vis[105][105];
int dxy[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
int dfs(int x,int y){
if(vis[x][y]) return vis[x][y];
vis[x][y] = 1;
for(int i = 0;i < 4;i ++){
int dx = x + dxy[i][0];
int dy = y + dxy[i][1];
if(dx > 0 && dy > 0 && dx <= n && dy <= m && mp[x][y] > mp[dx][dy]){
dfs(dx,dy);
vis[x][y] = max(vis[x][y],vis[dx][dy] + 1);
}
}
return vis[x][y];
}
int ans = 0;
int main(){
cin >> n >> m;
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= m;j ++){
cin >> mp[i][j];
}
}
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= n;j ++){
ans = max(ans,dfs(i,j));
}
}
cout << ans << "\n";
return 0;
}
P2853 [USACO06DEC] Cow Picnic S
思路
首先,这个题看起来很简单,就把所有牧场全
代码
#include<iostream>
#include<cstring>
using namespace std;
int k,n,m;
int x[100005];
struct node{
int to,next;
}e[2 * 100005];
int h[100005];
bool vis[100005];
int cnt[100005];
int tot = 0;
inline void adge(int x,int y){
e[++ tot] = (node){y,h[x]};
h[x] = tot;
return;
}
void dfs(int x){
cnt[x] ++;
for(int i = h[x];i != -1;i = e[i].next){
int v = e[i].to;
if(!vis[v]){
vis[v] = 1;
dfs(v);
}
}
return;
}
int main(){
memset(h,-1,sizeof(h));
cin >> k >> n >> m;
for(int i = 1;i <= k;i ++){
cin >> x[i];
}
for(int i = 1;i <= m;i ++){
int u,v;
cin >> u >> v;
adge(u,v);
}
for(int i = 1;i <= k;i ++){
vis[x[i]] = 1;
dfs(x[i]);
memset(vis,0,sizeof(vis));
}
int ans = 0;
for(int i = 1;i <= n;i ++){
if(cnt[i] == k){
ans ++;
}
}
cout << ans << "\n";
return 0;
}
P8604 [蓝桥杯 2013 国 C] 危险系数
思路
因为我们要求其关键点个数,所以呢我们可以“人性”一点,每次封锁一个点,跑一遍
代码
#include<vector>
#include<iostream>
#include<cstring>
using namespace std;
vector<int> G[1005];
int n,m,ans = 0;
int fx,fy;
bool v1[1005]={0,0};
bool r[1005]={0,0};
void dfs(int x){
if(v1[x]) return;
if(r[x]) return;
v1[x] = 1;
for(auto v:G[x]){
dfs(v);
}
return;
}
int main(){
cin >> n >> m;
for(int i = 1;i <= m;i ++){
int u,v;
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
cin >> fx >> fy;
dfs(fx);
if(v1[fy] == 0){
cout << "-1\n";
return 0;
}
for(int i = 1;i <= n;i ++){
if(i == fx || i == fy){
continue;
}
memset(v1,0,sizeof(v1));
r[i] = 1;
dfs(fx);
r[i] = 0;
if(v1[fy] == 0){
ans ++;
}
}
cout << ans <<"\n";
return 0;
}
P1294 高手去散步
思路
首先,用链式前向星存一下信息,为了使他们达到最长的相伴距离,那么就是找一条路,使其边权和最大,如何操作呢,我们可以从
代码
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
struct node{
int to,next,len;
}e[10005];
int h[10005];
int vis[10005];
int tot = 0;
inline void adge(int x,int y,int len){
e[++ tot] = (node){y,h[x],len};
h[x] = tot;
return;
}
int n,m,ans=0,maxx=-1;
void dfs(int x){
for(int i = h[x];i != -1;i = e[i].next){
int v = e[i].to;
int w = e[i].len;
if(vis[v] == 0){
vis[v] = 1;
ans += w;
maxx = max(maxx,ans);
dfs(v);
ans -= w;
vis[v] = 0;
}
}
}
int main(){
memset(h,-1,sizeof(h));
cin >> n >> m;
for(int i = 1;i <= m;i ++){
int u,v,w;
cin >> u >> v >> w;
adge(u,v,w);
adge(v,u,w);
}
for(int i = 1;i <= n;i ++){
vis[i] = 1;
dfs(i);
vis[i] = 0;
}
cout << maxx << "\n";
return 0;
}
P6207 [USACO06OCT] Cows on Skates G
思路
这个题吧,求
代码
#include<iostream>
#include<cstdio>
using namespace std;
int n,m;
char mp[150][150];
int pathx[100005];
bool vis[150][150];
int pathy[100005];
int dxy[4][2] = {{1,0},{0,-1},{-1,0},{0,1}};
void dfs(int x,int y,int id){
pathx[id] = x;
pathy[id] = y;
if(x == n && y == m){
for(int i = 1;i <= id;i ++){
cout << pathx[i] << " " << pathy[i] << "\n";
}
}
for(int i = 0;i < 4;i ++){
int dx = x + dxy[i][0];
int dy = y + dxy[i][1];
if(dx < 1 || dx > n || dy < 1 || dy > m || mp[dx][dy] == '*' || vis[dx][dy]){
continue;
}
vis[dx][dy] = 1;
dfs(dx,dy,id+1);
}
}
int main(){
cin >> n >> m;
for(int i = 1;i <= n;i ++){
scanf("%s",mp[i] + 1);
}
vis[1][1] = 1;
dfs(1,1,1);
return 0;
}
广度优先搜索
定义
别名“宽度优先搜索”,每次向下搜,一层一层搜。
习题
P1330 封锁阳光大学
思路
简单看下,发现无从下手,手动推一下,发现这是个染色问题,于是就
代码
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
struct node{
int to,next;
}e[500005];
int h[500005],color[500005],cnt[5];
int vis[500005];
int tot = 0;
inline void adge(int x,int y){
e[++ tot] = (node){y,h[x]};
h[x] = tot;
return;
}
int n,m,maxx=-0;
bool bfs(int x){
queue<int> q;
q.push(x);
color[x] = 1;
cnt[1] = 1,cnt[2] = 0;
while(!q.empty()){
int v = q.front();
q.pop();
for(int i = h[v];i != -1;i = e[i].next){
int t = e[i].to;
if(color[t] == color[v]){
return 1;
}
if(color[t] == 0){
color[t] = color[v] % 2 + 1;
cnt[color[t]] ++;
q.push(t);
}
}
}
return 0;
}
int main(){
memset(h,-1,sizeof(h));
cin >> n >> m;
for(int i = 1;i <= m;i ++){
int u,v;
cin >> u >> v;
adge(u,v);
adge(v,u);
}
for(int i = 1;i <= n;i ++){
if(color[i]) continue;
if(bfs(i)){
cout << "Impossible" << "\n";
return 0;
}
maxx += min(cnt[1],cnt[2]);
}
cout << maxx << "\n";
return 0;
}
本文来自一名初中牲,作者:To_Carpe_Diem
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!