zoukankan      html  css  js  c++  java
  • 搜索 A与A* 分支界限法搜索

    Problem Description
    题目原文是英文的,而且比较繁琐。我修饰转述如下:
    小强被海盗抓到了,海盗把他和他的船“小强号”关在一个水狱里。
    小强拿到了小红给他的一张水狱地图,地图由h行w列字符组成(3 <= h;w <= 500), ,字符共有四种:

    S:小强和他的“小强号”的起始位置,他要从这里逃跑。
    #:不能逾越的石墙
    . : 水道,小强号可以直接通过
    @:栅栏水道

    已知:
    小强打开栅栏需要d分钟 (0 <= d <= 50);
    小强号通过单位水道的时间为1分钟;
    水狱一定有出口。

    输入:
    t (一共有t组测试数据)
    h w d 以及水狱地图 (每组测试数据输入一次)
    输出:
    小强出狱的最短时间(和路线)。

     

    Sample Input

    2
    6 5 7
    #####
    #S . .#
    #@# .#
    # . . .#
    #@###
    # .###

    4 5 3
    #####
    #S#  .#
    #@ . .#
    ###@#

    Sample Output

    16

    11
    分析:
    从S点开始,广度优先搜索,寻找出口。

    code广度优先搜索

     1 //code:(普通广度搜索,超时)
     2 #include<iostream>
     3 #include<queue>
     4 using namespace std;
     5 #define N 501
     6 int h,w,d,sx,sy,t,big,i,j;
     7 int tv[N][N];   //到达水域某个位置的最短时间
     8 char maze[N][N];//记录水狱的地图
     9 int offset[4][2]={{-1,0},{0,-1},{1,0},{0,1}};//可以移动的四个方向
    10 struct pos
    11 {int x;int y;};
    12 int bfs()
    13 {
    14     int mymin=big;
    15     pos start,temp,temp1;
    16     start.x=sx,start.y=sy;
    17     tv[sx][sy]=0;
    18 
    19     queue<pos> q;
    20     q.push(start);
    21     while(!q.empty())
    22     { 
    23         temp=q.front();
    24         q.pop();
    25         //检测是否逃出水域,更新最短逃出时间
    26         if(temp.x==0||temp.x==h-1||temp.y==0||temp.y==w-1)
    27             if(mymin>tv[temp.x][temp.y]+1)
    28                 mymin=tv[temp.x][temp.y]+1;
    29         //探索当前位置的下一个位置
    30         for(i=0;i<4;i++)
    31         {
    32             pos temp1;//下一步的位置
    33             temp1.x=temp.x+offset[i][0];
    34             temp1.y=temp.y+offset[i][1];
    35             //判断下一步的位置是否超出地图
    36             if(temp1.x<0||temp1.x>=h||temp1.y<0||temp1.y>=w)
    37                 continue;
    38             //下一步的位置是水道
    39             if(maze[temp1.x][temp1.y]=='.')
    40             {
    41                 if(tv[temp1.x][temp1.y]>tv[temp.x][temp.y]+1)
    42                 {
    43                     tv[temp1.x][temp1.y]=tv[temp.x][temp.y]+1;
    44                     q.push(temp1);
    45                 }
    46             }
    47             //下一步的位置是栅栏
    48             if(maze[temp1.x][temp1.y]=='@')
    49             {
    50                 if(tv[temp1.x][temp1.y]>tv[temp.x][temp.y]+d+1)
    51                 {
    52                     tv[temp1.x][temp1.y]=tv[temp.x][temp.y]+1+d;
    53                     q.push(temp1);
    54                 } 
    55             }
    56         } 
    57     }
    58     return mymin;
    59 }
    60 int main()
    61 {
    62     cin>>t;
    63     while(t--)
    64     {
    65         cin>>h>>w>>d;
    66         big=h*w*d;//逃出水域的时间的上限
    67         getchar();
    68         for(i=0;i<h;i++)
    69         {
    70             for(j=0;j<w;j++)
    71             {
    72                 scanf("%c",&maze[i][j]);//cin>>maze[i][j];
    73                 tv[i][j]=big; 
    74                 if(maze[i][j]=='S')//小强出逃的起点位置
    75                 {sx=i;sy=j;}
    76             }
    77             getchar();
    78         } 
    79         printf("%d\n",bfs());//cout<<bfs()<<endl;
    80     }
    81     //for(;;);
    82 }
    View Code

    由于有栅栏,不能保证搜索的当前结点是“耗时最少”的优先搜索,对当前结点耗时v取权重,采用优先队列。

    code:改用优先队列,以到达该结点的时间v为权重,每次使v最小的结点出队,即所谓“A算法

     1 #include<iostream>
     2 #include<queue>
     3 using namespace std;
     4 #define N 501
     5 int h,w,d,sx,sy,t,i,j;
     6 bool used[N][N];
     7 char maze[N][N];
     8 int offset[4][2]={{-1,0},{0,-1},{1,0},{0,1}};//方向数组
     9 struct pos
    10 {int x;int y;int v;};
    11 struct cmp//这样之后出队序列就是由小到大,搜索结点时优先搜索v(从S到当前结点耗费的时间)小的结点。
    12 {
    13     bool operator()(const pos &p1,const pos &p2)
    14         return p1.v>p2.v; 
    15 };
    16 int bfs()
    17 {
    18     pos start,temp,temp1;//start为搜索起点,temp为当前搜索的结点,temp1为当前结点的扩展结点
    19     start.x=sx,start.y=sy,start.v=0;
    20     priority_queue<pos,vector<pos>,cmp> q;//注意拉,用优先级队列,小根堆
    21     q.push(start);
    22     while(!q.empty())
    23     { 
    24         temp=q.top();
    25         q.pop();
    26         //若temp结点从队列中出来,一定是水道或者栅栏,如果处于地图边缘,只要在该位置划船1分钟就出水狱了
    27         if(temp.x==0||temp.x==h-1||temp.y==0||temp.y==w-1)
    28             return temp.v+1;
    29         //对当前结点进行上下左右四个方向的搜索 
    30         for(i=0;i<4;i++)
    31         {
    32             pos temp1;
    33             temp1.x=temp.x+offset[i][0];
    34             temp1.y=temp.y+offset[i][1];
    35             //拓展位置如果超过地图或者先前已经被搜索过,直接略过
    36             if(used[temp1.x][temp1.y]==1||temp1.x<0||temp1.x>=h||temp1.y<0||temp1.y>=w)
    37                 continue;
    38             //拓展结点为 "." 水道,可以入队
    39             if(maze[temp1.x][temp1.y]=='.')
    40             {
    41                 temp1.v=temp.v+1;
    42                 q.push(temp1);
    43                 used[temp1.x][temp1.y]=1;
    44             }
    45             //拓展结点temp1为“@”栅栏,可以入队,入队时已经算好从S到temp1的时间 temp1.v
    46             if(maze[temp1.x][temp1.y]=='@')
    47             {
    48                 temp1.v=temp.v+1+d;
    49                 q.push(temp1);
    50                 used[temp1.x][temp1.y]=1;
    51             }
    52         } 
    53     }
    54 }
    55 int main()
    56 {
    57     cin>>t;
    58     while(t--)
    59     {
    60         cin>>h>>w>>d;
    61         getchar();//为了在后面使用scanf读入字符,解决换行问题
    62         for(i=0;i<h;i++)
    63         {
    64             for(j=0;j<w;j++)
    65             {
    66                 scanf("%c",&maze[i][j]);
    67                 used[i][j]=0; 
    68                 if(maze[i][j]=='S')
    69                 {sx=i;sy=j;}
    70             }
    71             getchar();//为了使用scanf读入字符,解决换行问题
    72         } 
    73         printf("%d\n",bfs());
    74     }
    75 }
    View Code

    codeA*算法
    在A算法基础上做改进,对结点以预测总耗费时间作为权重按由小到大排序。
    预测总耗费时间=当前耗费时间+预期最小耗费时间。
    预期最小耗费时间=该结点距离地图最近边缘的距离。
    只需要在源代码上修改队列排序函数:cmp  

    int mymin(int a,int b,int c,int d)
    {
        a=a<b?a:b;
        c=c<d?c:d;
        return (a<c?a:c); 
    }
    struct cmp{
        bool operator()(const pos &p1,const pos &p2)
        {return (p1.v+mymin(p1.x,p1.y,h-1-p1.x,w-1-p1.y)>p2.v+mymin(p2.x,p2.y,h-1-p2.x,w-1-p2.y));}
    };

    code:在A算法基础上打印路径

    View Code
      1 #include<iostream>
      2 #include<queue>
      3 using namespace std;
      4 #define N 501
      5 int h,w,d,sx,sy,t,i,j,ex,ey;
      6 struct pos
      7 {int x;int y;int v;};
      8 int offset[4][2]={{-1,0},{0,-1},{1,0},{0,1}};//方向数组 up left down right 
      9 bool used[N][N];
     10 char maze[N][N];
     11 pos lastp[N][N];
     12 struct cmp//这样之后出队序列就是由小到大,搜索结点时优先搜索v(从S到当前结点耗费的时间)小的结点。
     13 {
     14 bool operator()(const pos &p1,const pos &p2)
     15 {return (p1.v>p2.v);}
     16 };
     17 int bfs()
     18 {
     19 pos start,temp,temp1;//start为搜索起点,temp为当前搜索的结点,temp1为当前结点的扩展结点
     20 start.x=sx,start.y=sy,start.v=0;
     21 priority_queue<pos,vector<pos>,cmp> q;//注意拉,用优先级队列,小根堆
     22 q.push(start);
     23 while(!q.empty())
     24 { 
     25 temp=q.top();
     26 q.pop();
     27 //若temp结点从队列中出来,一定是水道或者栅栏,如果处于地图边缘,只要在该位置划船1分钟就出水狱了
     28 if(temp.x==0||temp.x==h-1||temp.y==0||temp.y==w-1)
     29 {
     30 ex=temp.x;
     31 ey=temp.y; 
     32 return temp.v+1;
     33 }
     34 //对当前结点进行上下左右四个方向的搜索 
     35 for(i=0;i<4;i++)
     36 {
     37 pos temp1;
     38 temp1.x=temp.x+offset[i][0];
     39 temp1.y=temp.y+offset[i][1];
     40 //拓展位置如果超过地图或者先前已经被搜索过,直接略过
     41 if(used[temp1.x][temp1.y]==1||temp1.x<0||temp1.x>=h||temp1.y<0||temp1.y>=w)
     42 continue;
     43 //拓展结点为 "." 水道,可以入队
     44 if(maze[temp1.x][temp1.y]=='.')
     45 {
     46 temp1.v=temp.v+1;
     47 q.push(temp1);
     48 used[temp1.x][temp1.y]=1;
     49 lastp[temp1.x][temp1.y].x=temp.x;
     50 lastp[temp1.x][temp1.y].y=temp.y;
     51 lastp[temp1.x][temp1.y].v=temp1.v;
     52 }
     53 //拓展结点temp1为“@”栅栏,可以入队,入队时已经算好从S到temp1的时间 temp1.v
     54 if(maze[temp1.x][temp1.y]=='@')
     55 {
     56 temp1.v=temp.v+1+d;
     57 q.push(temp1);
     58 used[temp1.x][temp1.y]=1;
     59 lastp[temp1.x][temp1.y].x=temp.x;
     60 lastp[temp1.x][temp1.y].y=temp.y;
     61 lastp[temp1.x][temp1.y].v=temp1.v;
     62 }
     63 } 
     64 }
     65 }
     66 void show()
     67 {
     68 
     69 printf("the path:\n");
     70 cout<<ex<<" "<<ey<<endl;
     71 int i,j;
     72 i=ex,j=ey;
     73 while(maze[i][j]!='S')//(!(i==sx&&j==sy))
     74 {
     75 maze[i][j]=' ';
     76 cout<<i+1<<" "<<j+1<<endl;
     77 int ii,jj;
     78 ii=i;jj=j;
     79 i=lastp[ii][jj].x;
     80 j=lastp[ii][jj].y;
     81 }
     82 printf("the route:\n");
     83 for(i=0;i<h;i++)
     84 {
     85 for(j=0;j<w;j++)
     86 {
     87 cout<<maze[i][j]; 
     88 } 
     89 cout<<endl;
     90 }
     91 cout<<endl;
     92 }
     93 int main()
     94 {
     95 cin>>t;
     96 while(t--)
     97 {
     98 cin>>h>>w>>d;
     99 getchar();//为了在后面使用scanf读入字符,解决换行问题
    100 for(i=0;i<h;i++)
    101 for(j=0;j<w;j++)
    102 used[i][j]=0;
    103 for(i=0;i<h;i++)
    104 {
    105 for(j=0;j<w;j++)
    106 {
    107 scanf("%c",&maze[i][j]);
    108 used[i][j]=0;
    109 if(maze[i][j]=='S')
    110 {sx=i;sy=j;}
    111 }
    112 getchar();//为了使用scanf读入字符,解决换行问题
    113 } 
    114 printf("the shortest time:%d\n",bfs());
    115 show();
    116 }
    117 
    118 }

     测试数据:

    View Code
     1 2
     2 6 5 7
     3 #####
     4 #S..#
     5 #@#.#
     6 #...#
     7 #@###
     8 #.###
     9 the shortest time:16
    10 the path:
    11 5 1
    12 6 2
    13 5 2
    14 4 2
    15 4 3
    16 4 4
    17 3 4
    18 2 4
    19 2 3
    20 the route:
    21 #####
    22 #S #
    23 #@# #
    24 # #
    25 # ###
    26 # ###
    27 
    28 4 5 3
    29 #####
    30 #S#.#
    31 #@..#
    32 ###@#
    33 the shortest time:11
    34 the path:
    35 3 3
    36 4 4
    37 3 4
    38 3 3
    39 3 2
    40 the route:
    41 #####
    42 #S#.#
    43 # #
    44 ### #


    迷宫问题
    A*从n*n的举证左上角走到右下角的最短用时:
    /*
    迷宫问题,找一条最短的路径。
    初始状态:(0,0)
    终止状态:(n-1, n-1)
    g(i,j): (0,0) 到 (i,j)的路径长度;
    h(i,j): (i,j) 到(n-1,n-1)的路径长度的估计值;
    h(i,j)=2n-i-j;

    *表示障碍
    o表示通道

    给出一个地图,求从地图左上角到达右下角需要的最短时间
    */

    代码:

     1 #include<iostream>
     2 #include<queue>
     3 #define M 201
     4 using namespace std;
     5 struct pos {int x;int y;int v;};
     6 pos offset[4]={{-1,0},{1,0},{0,1},{0,-1}};//一个店的相邻位置
     7 char maze[M][M]; //maze记录地图的布置
     8 int step[M][M];  //step[i][j]表示达到i,j位置的最优步数
     9 int m,n;
    10 struct cmp
    11 {
    12     //用于优先级队列中的堆排序,A算法。
    13     bool operator()(const pos &p1,const pos &p2)
    14     {
    15         return (p1.v+(m+n-p1.x-p1.y) > p2.v+(m+n-p2.x-p2.y));
    16     }
    17 };
    18 int BFS(pos start)
    19 {
    20     pos headNode,neibNode;
    21     step[start.x][start.y]=0; 
    22     priority_queue<pos,vector<pos>,cmp> q;
    23     q.push(start);
    24     while(!q.empty())
    25     { 
    26         headNode=q.top();
    27         q.pop(); 
    28         for(int i=0;i<4;i++) 
    29         { 
    30             neibNode.x = headNode.x + offset[i].x;
    31             neibNode.y = headNode.y + offset[i].y;
    32             neibNode.v = headNode.v + 1; 
    33             //相邻点超过边界,过滤掉
    34             if( neibNode.x>=m || neibNode.y>=n || neibNode.x<0 || neibNode.y<0 ) 
    35                 continue; 
    36             //相邻点为石头 或者 不是最优尝试,过滤掉
    37             if( maze[neibNode.x][neibNode.y]=='*' || neibNode.v>=step[neibNode.x][neibNode.y]) 
    38                 continue; 
    39             q.push(headNode);
    40             step[headNode.x][headNode.y]=next.v; 
    41             //如果到达目的地,返回
    42             if( neibNode.x==m-1 && neibNode.y==n-1 ) 
    43                 return headNode.v; 
    44         }
    45     }
    46     return 0; 
    47 } 
    48 int main() 
    49 { 
    50     int i,j;
    51     pos start;
    52     start.x=0;start.y=0;start.v=0;
    53     while(cin>>n)
    54     { 
    55         m=n;
    56         for(i=0;i<m;i++) 
    57         {
    58             for(j=0;j<n;j++)
    59             {
    60                 cin>>maze[i][j];
    61                 step[i][j]=m*n;
    62             }
    63         }
    64         cout<<BFS(start)<<endl;
    65     } 
    66 }
    View Code

    测试数据:

    View Code

    网上转的priority_queue用法的例子 转自http://blog.sina.com.cn/s/blog_5e518b010100kbts.html

    STL之优先队列

    原本以为priority_queue很简单,才知道原来懂的只是最简单的形式。

    头文件:#include<queue>

    优先队列,也就是原来我们学过的堆,按照自己定义的优先级出队时。默认情况下底层是以Vector实现的heap。

    既然是队列,也就只有入队、出队、判空、大小的操作,并不具备查找功能。

    函数列表:
      empty() 如果优先队列为空,则返回真
      pop() 删除第一个元素
      push() 加入一个元素
      size() 返回优先队列中拥有的元素的个数  
      top() 返回优先队列中有最高优先级的元素

    用途就不用多说了吧,例如Huffman编码、分支限界、A*启发式都需要用到优先队列存放信息。

    来看最常用的几个功能,了解一下其中的知识点:

    一:最基本的功能

                
       

    #include<iostream>

       

    #include<queue>

       

    using namespace std;

       

    int main()

       

    {

       

    priority_queue<int> Q;

       

    Q.push(2);

       

    Q.push(5);

       

    Q.push(3);

       

    while(!Q.empty())

       

    {

       

    cout<<Q.top()<<endl;

       

    Q.pop();

       

    }

       

    system("pause");

       

    return 0;

       

    }

       
       

    优先队列最基本的功能就是出队时不是按照先进先出的规则,而是按照队列中优先级顺序出队。

       

    知识点:1、一般存放实型类型,可比较大小

       

    2、默认情况下底层以Vector实现

       

    3、默认情况下是大顶堆,也就是大者优先级高,后面可以自定义优先级比较规则

       

    二:次基本的功能

                
       

    #include<iostream>

       

    #include<queue>

       

    using namespace std;

       

    int main()

       

    {

       

    int a[5]={3,4,5,2,1};

       

    priority_queue<int> Q(a,a+5);

       

    while(!Q.empty())

       

    {

       

    cout<<Q.top()<<endl;

       

    Q.pop();

       

    }

       

    system("pause");

       

    return 0;

       

    }

       
       

    可以将一个存放实型类型的数据结构转化为优先队列,这里跟优先队列的构造函数相关。

       

    上面那个默认构造一个空的优先队列,什么都使用默认的。

       

    而这里使用的是

       

    Priority_queue(InputIterator first,InputIterator last)

       

    我理解的就是给出了一个容器的开口和结尾,然后把这个容器内容拷贝到底层实现(默认vector)中去构造出优先队列。这里也使用了一个默认的比较函数,也是默认大顶堆

       

    三 应该掌握的功能:

                
       

    #include<iostream>

       

    #include<queue>

       

    using namespace std;

       

    typedef pair<long,int> Node;

       

    priority_queue< Node,vector< Node >,greater< Node >     > Q;

       
       

    这个里面定义了一个制定存放元素(Node),底层实现以vector实现(第二个参数),优先级为小顶堆(第三个参数)。

       

    前两个参数没什么说的,很好理解,其中第三个参数,默认有三写法:

       

    小顶堆:greater<TYPE>

       

    大顶堆:less<TYPE>

       

    如果想自定义优先级而TYPE不是基本类型,而是复杂类型,例如结构体、类对象,则必须重载其中的operator(),见下面的例子。

       

    例子:

            
       

    #include<iostream>

       

    #include<queue>

       

    using namespace std;

       

    //模拟存放节点信息

       

    typedef struct

       

    {

       

    int a;

       

    int b;

       

    }Node;

       

    //自定义优先级类型

       

    struct cmp

       

    {

       

    bool operator()(const Node &t1,const Node &t2)

       

    {

       

    return t1.b<t2.b;//相当于less,大顶堆

       

    }

       

    };

       

    int main()

       

    {

       

    //初始化

       

    int n;

       

    cin>>n;

       

    Node *arr=new Node[n];

       

    for(int i=0;i<n;i++)

       

    {

       

    cin>>arr[i].a>>arr[i].b;

       

    }

       

    //定义优先队列 ,自定义优先级,跟Qsort里面自定义相似

       

    priority_queue<Node,vector<Node>,cmp> Q(arr,arr+n);

       

    while(!Q.empty())

       

    {

       

    Node n=Q.top();

       

    cout<<n.a<<" "<<n.b<<endl;

       

    Q.pop();

       

    }

       

    system("pause");

       

    return 0;

       

    }

       

    问题描述:
    有一个背包,容重为W,有n件物品,每件物品对应一个物品价值v和物品重量w。装哪些物品到背包中可使包中价值最大?
    输入:
    W n
    (W表示背包容量 n表示物品数量)
    接下来再输入n行 每行为两个正整数 w v(分别表示一个物品的重量和价值)

    输出:
    bestsum (表示背包中能装物品的最大价值)
    best choice(表示背包中最大价值为物品选择方式)

    sample in:
    75 4
    20 20
    10 20
    30 24
    45 35
    sample out:
    best choice:0,1,3
    best sum:75
    分析:


    分支界限分析:
    1.
    假设现在正在处理节点temp,
    如果temp.wleft>=good[temp.num].w
    就不进行temp的next1拓展,即不把第temp.num放入背包。
    这是对广搜完全遍历的一种剪枝

    2.
    假设现在正在处理节点temp,temp的最大价值期望为expectsumv
    expectsumv=temp.vsum+good[temp.num].v*temp.wleft/good[temp.num].w;
    如果expectsumv<=bestsum,该节点就不值得被扩展。这样temp节点的子树就被剪枝了
                           
    code

      1 #include<iostream>
      2 #include<queue>
      3 #include<algorithm>
      4 using namespace std;
      5 
      6 int W,n,bestSum,lowbound;
      7 string bestChoice;
      8 //node indicates good
      9 struct node
     10 {
     11     int w;
     12     int v; 
     13 };
     14 node good[1000];
     15 //node2 indicates searching node
     16 struct node2
     17 {
     18     int num;//consider which good,the numth good has been considered,0 means none goods has been dealt; 
     19     //num=2 表示good【0】和good【1】已经考虑过了 
     20     int wleft;//weight left
     21     int vsum; // sum of value
     22     string choice;//a string of choice 
     23 };
     24 struct cmp
     25 {
     26     bool operator()(const node2 &p1,const node2 &p2)
     27     {
     28         // p.num==n,表示叶子节点,叶子节点优先 
     29         if(p1.num==n)
     30             return 1;
     31         if(p2.num==n)
     32             return 0;
     33         // 非叶子节点通过上界算优先级 
     34         return (p1.vsum+float(good[p1.num].v*p1.wleft)/float(good[p1.num].w))>(p2.vsum+float(good[p2.num].v*p2.wleft)/float(good[p2.num].w));
     35         //return (p1.vsum+float(good[p1.num].v*p1.wleft)/float(good[p1.num].w))>(p2.vsum+float(good[p2.num].v*p2.wleft)/float(good[p2.num].w));
     36 
     37     }
     38 };
     39 
     40 bool cmpnode(const node &a,const node &b)
     41 {
     42     return a.v*b.w>b.v*a.w; 
     43 }
     44 void bfs(node2 start)
     45 {
     46 
     47     priority_queue<node2,vector<node2>,cmp> q;
     48     q.push(start);
     49     while(!q.empty())
     50     {
     51         node2 temp=q.top();
     52         q.pop(); 
     53         if(temp.num==n)
     54         {
     55             if(temp.vsum>bestSum)
     56             {
     57                 bestSum=temp.vsum;
     58                 bestChoice=temp.choice;
     59             }
     60         }
     61         //分支界限约束2 
     62         //该节点的最好期望比 已知可行的bestSum下界高 才扩展该活结点 
     63         //if(temp.vsum+good[temp.num].v*temp.wleft/good[temp.num].w>=bestSum)
     64         else if(temp.vsum*good[temp.num].w+good[temp.num].v*temp.wleft>bestSum*good[temp.num].w)
     65         {
     66             //add good[temp.num]
     67             if(temp.wleft>=good[temp.num].w)// 分支界限约束1 
     68             {
     69                 node2 next1;
     70                 next1.num=temp.num+1;
     71                 next1.vsum=temp.vsum+good[temp.num].v;
     72                 next1.wleft=temp.wleft-good[temp.num].w;
     73                 //莫名奇妙的错误,当char *strnum,时出错 segmentation error。 
     74                 char strnum[1000];
     75                 itoa(temp.num,strnum,10);
     76                 string str=strnum;
     77                 next1.choice=temp.choice+str+" ";
     78                 //next1.choice+=(strnum);
     79                 //cout<<next1.choice<<endl;
     80                 q.push(next1);
     81             }
     82             //not add good[temp.num]
     83             node2 next0;
     84             next0.num=temp.num+1;
     85             next0.vsum=temp.vsum;
     86             next0.wleft=temp.wleft;
     87             next0.choice=temp.choice;
     88             q.push(next0); 
     89         } 
     90     }
     91 }
     92 int main()
     93 {
     94     int i,j,k;
     95     while(cin>>W>>n)
     96     {
     97         for(i=0;i<n;i++)
     98             cin>>good[i].w>>good[i].v;
     99         sort(good,good+n,cmpnode);
    100         cout<<"put in order accordingto v/w by decrease"<<endl;
    101         for(i=0;i<n;i++)
    102             cout<<good[i].w<<" "<<good[i].v<<endl;
    103 
    104         bestChoice="";
    105         bestSum=0;
    106         //lowbound=0;
    107         /*
    108         bestSum目前知道的可行的最好情况(也是节点拓展的下界),如果节点的最好期望 小于下界,则不值得拓展,成为死节点 
    109         当有叶子节点出队时更新。 
    110         */
    111         node2 start;
    112         start.num=0;
    113         start.wleft=W;
    114         start.vsum=0;
    115         start.choice="";
    116         //cout<<"*******"<<endl;
    117         bfs(start);
    118 
    119         cout<<"best choice: "<<bestChoice<<endl;
    120         cout<<"best sum is:"<<bestSum<<endl;
    121 
    122     }
    123 }
    View Code


    /*
    75 4
    20 20
    10 20
    30 24
    45 35
    */

  • 相关阅读:
    struts传值方式ModelDriven的使用
    sql查询count 单独字段不同值
    图片-文件上传下载
    HTML 字符实体 &lt; &gt: &amp;等
    Validation failed for object='employee'. Error count: 1问题解决
    MySQL查询本周、上周、本月、上个月份数据的sql脚本
    React前端框架路由跳转,前端回车事件、禁止空格、提交方式等方法
    环境变量误删path找回方法与mysql基础命令
    树结构的控制
    数据库查询方法
  • 原文地址:https://www.cnblogs.com/huangzq/p/2997829.html
Copyright © 2011-2022 走看看