DFS(深度优先搜索)
引入:为什么要搜索解决问题?
因为很多问题并不可以直接计算出结果,需要遍历所有情况才能发找到最优解或者可行解。
深度优先搜索:
采用递归的方法,先沿一条路搜到底,在递归回上一个节点,沿另一个方向搜索,以此类推。
类似于树的先根遍历;
思想:一直往深处走,直到找到解或者走不下去为止
模板:
int MAXN=0;
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
bool can_move(int x,int y)
{
if(...) //越界情况
return false;
if(...) //非法情况
return false;
return true;
}
void dfs(int x,int y,int ans)
{
if(x==ex&&y=ey)
{
MAXN=max(MAXN,ans);
}
visit[x][y]=1;
for(int i=0;i<4;i++)
{
int tx=x+dx[i];
int ty=y+dy[i];
if(can_move(tx,ty))
dfs(tx,ty,ans+1);
}
visit[x][y]=0;
return;
}
当然模板并非一成不变,对于具体问题要具体分析。但是大致的思路总是相同。
剪枝问题:
剪枝是一种优化方式,对于不同的问题有着不同的方法。通常分为以下两类:
1.最优化剪枝
2.可行性剪枝
实例分析:
问题:
N个城市,编号1到N。城市间有R条单向道路。每条道路连接两个城市,有长度和过路费两个属性。Bob只有K块钱,他想从城市1走到城市N。问最短共需要走多长的路。如果到不了N,输出-1
2<=N<=100
0<K<=10000
1<=R<=10000
每条路的长度 L, 1 <= L <= 100
每条路的过路费T , 0 <= T <= 100
思路:从城市 1开始深度优先遍历整个图,找到所有能过到达 N 的走法,选一个最优的。
如何剪枝?
1.最优化剪枝:如果当前已经找到的最优路径长度为L ,那么在继续搜索的过程中,总长度已经大于等于L的走法,就可以直接放弃,不用走到底了
2.可行性剪枝:如果当前到达城市的路费已大于k,或者等于k且没有到达终点,就可以直接放弃。
此篇只作简要剖析,刷题记录另开文章