详细介绍参考:图的遍历之 深度优先搜索和广度优先搜索
剪格子
蓝桥杯剪格子参考思路
注意回溯的时候要更改标记状态
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int a[10][10];
int visited[10][10];//访问标记数组
int dx[4]={-1,1,0,0};//dx,dy用来控制移动方向
int dy[4]={0,0,-1,1};//上,下,左,右
int n, m, half, t, mint;//half为总和的一半,t用来记录走过的格子数
void dfs(int x, int y, int sum, int t){
if(sum == half){
if(visited[0][0]==1){
if(t<mint) mint = t;
return;
}
}
for(int i = 0; i < 4; i++){
int nx = x + dx[i];
int ny = y + dy[i];
if(nx<n && nx>=0 && ny<m && ny>=0 && !visited[nx][ny]){
visited[nx][ny] = 1;
dfs(nx,ny,sum+a[nx][ny],t+1);
visited[nx][ny] = 0;//回溯时记得更改访问标记状态
}
}
}
int main(){
int s = 0;
cin>>m>>n;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin>>a[i][j];
s += a[i][j];
}
}
memset(visited,0,sizeof(visited));
mint = 101;
if(s%2 != 1){//总和不为奇数才有可能分割成功
half = s/2;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
visited[i][j] = 1;
dfs(i,j,a[i][j],1);
visited[i][j] = 0;
}
}
if(mint==101) //无法分割
cout<<0<<endl;
else cout<<mint<<endl;
}
else cout<<0<<endl;
return 0;
}
大臣的旅费
这题其实就是求树的直径,即树的最长简单路,用两遍 dfs即可。
利用了树的直径的一个性质:距某个点最远的点一定是直径的一个端点。
随机挑选一个点开始第一遍 dfs,先找到一个端点
a
a
a,然后再以这个
a
a
a点为起点做dfs找到离该点最远的点
b
b
b,这
a
,
b
a,b
a,b两点之间的距离就是树的直径。
思路参考:树的直径,树的最长路的DP思想
代码中关于结构体的一些问题:结构体知识整理
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
struct node{
int v;//编号
int w;//到这个点的距离
node(int value,int weight):v(value),w(weight){}//结构体中的构造函数
};
vector<vector<node> > cityRoad;
int n;//(城市)结点个数
int endNode;//离出发点最远的点
int result[10010];//存储从某一点出发到其他点的距离值,只需要求最大距离时其实不需要它
int maxLen;//只要这个就够了
void dfs(int beginNode,int preNode,int distance){ //距离某个点的最长的距离 length 是与起始点的距离
/*//为了能更好的理解递归过程,可以看看这个输出
cout<<"begin_node: "<<begin_node<<" father: "<<father<<endl;
for(int i=1;i<=n;i++)
cout<<"result["<<i<<"]: "<<result[i]<<endl;
cout<<endl;
*/
if(distance > maxLen){
maxLen = distance;
endNode = beginNode;
}
for(int i =0;i<cityRoad[beginNode].size();i++){//dfs 遍历与之相邻的所有点
if(cityRoad[beginNode][i].v != preNode){//不访问已经走过的点
result[cityRoad[beginNode][i].v] = distance +cityRoad[beginNode][i].w;
dfs(cityRoad[beginNode][i].v, beginNode, distance+cityRoad[beginNode][i].w);
}
}
}
int main(){
cin>>n;
cityRoad.resize(n+1);
memset(result,0,sizeof(result));
int a, b, c;
for(int i=1;i<n;i++){
cin>>a>>b>>c;
cityRoad[a].push_back(node(b,c));
cityRoad[b].push_back(node(a,c));
}
/* //show vector<vector<node> >
for(int i = 1; i <= n; i++){
cout<<i<<": ";
for(int j = 0; j < cityRoad[i].size(); j++)
cout<<cityRoad[i][j].v<<"("<<cityRoad[i][j].w<<") ";
cout<<endl;
}
*/
maxLen=0;
dfs(1,-1,0);
memset(result,0,sizeof(result));
dfs(endNode,-1,0);
/*//利用result找最大距离
int temp=0;
for(i=1;i<=n;i++)
temp =max(temp,result[i]);
cout<<temp*(temp+21)/2<<endl;
*/
cout<<maxLen*(maxLen+21)/2<<endl;//和上面结果相同
return 0;
}