- 定义
- 全排列
- 最短路径
- 自然数的拆分
- 高手散步
定义(不撞南墙不回头)
深度优先搜索(Depth-First Search,DFS)是十分常见的图搜索方法之一。深度优先搜索会沿着一条路径一直搜索下去,在无法搜索时,回退到刚刚访问过的节点。(一条路走到黑)
全排列
#include<stdio.h>
int n;//数字
int a[10];
int book[10];//标记
void dfs(int step){
if(step==n+1){
for(int i=1;i<=n;i++){
printf("%d ",a[i]);
}
printf("\n");
return;//返回上一步
}
for(int i=1;i<=n;i++)//尝试每种可能
{
if(book[i]=0)//如果这个牌在手上
{
a[step]=i;//step号箱子被放入i
book[i]=1;//i牌被标记
dfs(step+1);//去下一个箱子
book[i]=0;
}
}
return;
}
int main(){
scanf("%d",%n);
dfs(1);
}
最短路径
#include<stdio.h>
int n,m;
int startx,starty,p,q;
int book[20][20],a[20][20];
int min=9999999;
void dfs(int step,int x,int y){
if(x==p&&y==q){
if(step<min)//到达终点
{
min=step;
}
return ;
}
int next[4][2]={{0,1},//向右走
{1,0},//向下走
{0,-1},//向左走
{-1,0}//向上走
};
int tx,ty,k;
for(k=0;k<=3;k++)//每一种尝试
{
tx=x+next[k][0];
ty=y+next[k][1];//此时的位置
if(tx<1||ty<1||tx>n||ty>m)//如果走出边界
continue;
if(a[tx][ty]==0&&book[tx][ty]==0)//这点没有障碍并且没有被标记
{
book[tx][ty]=1;//标记这点
dfs(step+1,tx,ty);//下一步
book[tx][ty]=0;//返回时取消标记
}
}
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
}
}
scanf("%d %d %d %d",&startx,&starty,&p,&q);
book[startx][starty]=1;// 第一个位置标记掉
dfs(0,startx,starty);
printf("%d",min);
}
自然数的拆分
#include<stdio.h>
int a[10001]={1};
int n;//数字
void fff(int m,int t)//t是分成数字的个数(箱子数) m是剩余字的大小
{
int i;int k;
for(i=a[t-1];i<=m;i++)//当前数要比前面一个树大所以i从a[t-1]开始
{
if(i<n){
a[t]=i;//箱子中放
m-=i;//减去后还剩下的
if(m==0){
printf("%d",a[1]);
for(k=2;k<=t;k++){
printf("+");
printf("%d",a[k]);
}
printf("\n");
}
else{
fff(m,t+1);
m+=i;//回溯
}
}
}
}
int main()
{
scanf("%d",&n);
fff(n,1);
}
高手去散步
#include<stdio.h>
int d[23][23];
int x,y,f;
int book[23];//标记走过的景点
int n,max=0;//n为景点总数
void dfs(int k,int sum,int p)//走过的景点数 k和当前走过的距离sum 和当前的位置
{
int i;
if(sum>max)max=sum;
if(k==n) return ;//全部走完了 返回 换一条路
for( i=1;i<=n;i++){
if(d[p][i]>0&&book[i]==0)//当前位置能到i并且i位置未被标记
{
sum+=d[p][i];
book[i]=1;
dfs(k++,sum,i);//找下一条路
book[i]=0;//接触标记
sum-=d[p][i];
}
}
}
int main()
{
int m;int i;
scanf("%d %d",&n,&m);
for( i=1;i<=m;i++){
scanf("%d %d %d",&x,&y,&f);
d[x][y]=f;
d[y][x]=f;//双向路
}
for(i=1;i<=n;i++)//尝试不同的起点
{
book[i]=1;//标记
dfs(1,0,i);
book[i]=0;//回溯
}
printf("%d",max);
}