ACM——穷举搜索

  1. DFS(深度优先)
    (1)模板代码
bool visited[MAX_VERTEX_NUM]; //访问数组标记
void DFSTraverse(Graph G)
{
   //对图G深度遍历,访问函数是visit()
   for(v=0; v<G.vexnum;++v)
     visited[v]=FALSE; // 初始化访问标记
   for(v=0;v<G,vexnum;++v) //从v=0开始遍历
     if(!visited[v])
        DFS(G,v);
}
void DFS(Graph G, int v)
{ //从顶点v出发,采用递归,深度遍历
    visit(v); // 访问顶点v
    visited[v]=TRUE; //标记访问
    for(w=FirstNeighbor(G,v); w>=0;w=NextNeighor(G,v,w))
    //FirstNeighbor()=图G中顶点x的第一个领接点,有则返回序列号
    //NextNeighor()=如果y是x的一个领接点,返回除y之外的顶点x的下一个领接点号
      if(!visited[w])
        DFS(G,w);  
}

(2)题目练习
给定整数:a1,a2,…,ana1,a2,…,an, 判断是否可以从中选出若干数,是其和恰好是k
*限制条件
1<=n<=201<=n<=20
−108<=ai<=108−108<=ai<=108
−108<=k<=108

Input:
n=4
a={1,2,4,7}
k=13
Output:
YES {13=2+4+7}
代码:

#include 
using namespace std;
bool dfs (int i, int sum, int* a, int n, int k) {
    if (i==n) return sum == k;
    if(dfs(i+1, sum, a, n, k)) return true;
    if(dfs(i+1, sum+a[i], a, n, k)) return true;
    return false;
}
void solve(int* a, int n, int k) {
    if (dfs(0,0,a,n,k)) 
        cout<<"Yes"<<'\n';
    else 
        cout <<"No"<<'\n';
}
int main(void)
{
    const int MAX_N = 20;
    int a[MAX_N] = {1, 2, 4, 7};
    int n = 4, k = 13; //k位需要找到的数字
    solve(a, n, k);
    return 0;
}
  1. BFS(广度优先)
    (1) 模板
bool visited[MAX_VERTEX_NUM]//访问标记数组
 void BFSTraverse(Graph G){
 //图G进行广度优先遍历,设访问函数visit()
     for(i=0;i<G.vexnum;++i)
         visited[i]=FALSE
     InitQueue(Q);  //初始化辅助队列
     for(i=0;i<G.vexnum;++i) //从0开始遍历
         if(!visited[i])     //对每个连通分量调用BFS
             BFS(G,i); //vi 未访问,从vi开始BFS
 }
 void  BFS(Graph G, int v){
     visit(v); // 访问初始化顶点v
     visited[v]=TRUE; //对v做标记
     Enqueue(Q,v); //顶点v入队
     while(!isEmpty(Q)){
         DeQueue(Q,v); //顶点v出队列
         for(w=FristNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)) //检查v的所有领接点
             if(!visited[w]) //w是尚未检查的顶点
                 visited(w); //访问顶点
                 visited[w]=TRUE; //标记w
                 EnQueue(Q,w); //顶点w入队列
     }
 }

(2)题目练习:
给定一个大小是N*M的迷宫,每一步向领接的上下左右四格的通道移动。请求出从起点到终点所需的最小步数
限制条件:N,M<=100。
N=10,M=10
#: 墙壁;.:通道; S:起点 G:终点
Input:
#S########
…#…#
.#.##.##.#
.#…
##.##.####
…#…#
.#######.#
…#…
.####.###.
…#…G#
Output:22
(2)代码:

#include   
#include   
#include   
using namespace std;  
struct node  
{  
    int x,y,step;  
};  
char map[105][105];  
int vis[105][105];  
int to[4][2]= {1,0,-1,0,0,1,0,-1};  
int n,m,sx,sy,ex,ey,ans;  
int check(int x,int y)  
{  
    if(x<0 || x>=n || y<0 || y>=m)  
        return 1;  
    if(vis[x][y] || map[x][y]=='#')  
        return 1;  
    return 0;  
}  
void bfs()  
{  
    int i;  
    queue<node> Q;  
    node a,next;  
    a.x = sx;  
    a.y = sy;  
    a.step = 0;  
    vis[a.x][a.y]=1;  
    Q.push(a);  
    while(!Q.empty())  
    {  
        a = Q.front();  
        Q.pop();  
        if(map[a.x][a.y]=='E')  
        {  
            ans = a.step;  
            return ;  
        }  
        for(i = 0; i<4; i++)  
        {  
            next = a;  
            next.x+=to[i][0];  
            next.y+=to[i][1];  
            if(check(next.x,next.y))  
                continue;  
            next.step=a.step+1;  
            vis[next.x][next.y] = 1;  
            Q.push(next);  
        }  
    }  
    ans = -1;  
}  
int main()  
{  
    int t;  
    scanf("%d",&t);  
    while(t--)  
    {  
        scanf("%d%d",&n,&m);  
        int i,j;  
        for(i = 0; i<n; i++)  
            scanf("%s",map[i]);  
        for(i = 0; i<n; i++)  
        {  
            for(j = 0; j<m; j++)  
            {  
                if(map[i][j]=='S')  
                {  
                    sx = i;  
                    sy = j;  
                }  
            }  
        }  
        memset(vis,0,sizeof(vis));  
        bfs();  
        printf("%d\n",ans);  
    }  
    return 0;  
}  

参考博客:https://blog.csdn.net/mijian1207mijian/article/details/51030433

你可能感兴趣的:(算法,ACM)