XCPC 程序设计竞赛模板 搜索

DFS

实现

void dfs(int step)    //步长或图的一个顶点
{
 //访问标记
    if(/*跳出循环的条件*/) return;    //return十分关键,否则循环将会无法跳出
    /*函数主体,对功能进行实现*/
    for(/*对现有条件进行罗列*/){//该顶点的相邻节点
        if(/*判断是否合理*/){
            //将条件修改
            dfs(/*新的step*/)
            /*!重中之重,当跳出那层循环后将数据全部归位,即回溯*/
        }    
    }
}

优化

  • 可行性剪枝
  • 最优性剪枝
  • 重复性剪枝
  • 优化搜索顺序
  • 记忆化搜索

应用

  • 遍历图,小规模枚举搜索

回溯法

  • return 回溯时恢复所有改变

  • 遇到边界条件

  • 多次遍历

BFS

实现

void bfs(s) {
  q = new queue()
  q.push(s), visited[s] = true//1把起点放入到队列当中
  while (!q.empty()) {//4搜索到终点,算法结束(队列为空)
    u = q.pop()//3取出队列中的队首元素,重复步骤2
    for each edge(u, v) {
      if (!visited[v]) {
        q.push(v)//2从起点开始按照一定的规则走到其他的点,并放入队尾
        visited[v] = true
      }
    }
  }
}

优化

  • 剪枝同BFS
  • 记忆化搜索
  • 优先队列迭代思想

应用

  • 遍历图
  • 最短路问题
    • BFS 通过最短路径到达一个点

双向同时搜索&折半搜索

实现

折半搜索将数据和搜索过程分成两半搜索,然后再合并两半搜索的答案
双向同时搜索如下

将开始结点和目标结点加入队列 q
标记开始结点为 1
标记目标结点为 2
while (队列 q 不为空)
{
  从 q.front() 扩展出新的 s 个结点
  如果 新扩展出的结点已经被其他数字标记过
    那么 表示搜索的两端碰撞 循环结束
  如果 新的 s 个结点是从开始结点扩展来的
    那么 将这个 s 个结点标记为 1 并且入队 q 
  如果 新的 s 个结点是从目标结点扩展来的
    那么 将这个 s 个结点标记为 2 并且入队 q
}

优化

  • 折半搜索排序后二分、双指针、哈希表

应用

  • 寻找可行解且起终点确定用双向同时搜索
  • 搜索各项互不干扰且搜索状态可逆用折半搜索

启发式搜索

实现

  • 引入估价函数,估价函数代表完美估价,即实际下限

应用

  • 易构造估价函数

A*BFS

实现

  • 先记录当前成本g,加上估价函数h计算总成本f=g+h(完美估价,是花费代价的下限,最优解的代价)

  • 然后从优先队列openlist取出总成本最小的状态更新相邻状态,优先使用新得到的方格(访问标记closelist)

  • 添加父节点记录,到达终点后通过父节点返回得到最优路径

应用

  • 对多节点路径求出最低通过成本的图遍历、最佳优先搜索、最短路,估价函数易构造

迭代加深搜索IDDFS

实现

  • 每次DFS加上深度限制,近似BFS,寻找最优解

  • 回溯过程中记录最优路径

应用

  • 一定限制条件,输出所有解中的任意一组解

IDA*DFS

实现

  • 迭代加深进行最优性剪枝

  • 估价函数进行可行性剪枝

  • 第一个解即最优解,估价函数是每次状态改变过程中的不变量

应用

  • 题目限制条件,输出任意解,估价函数易求

DLX

实现

  • X算法
    1. 对现有矩阵 M 选择并标记一行 r ,将 r 添加至集合 S 中
    2. 尝试所有 r 无解,算法结束
    3. 标记与 r 相关的行和列,得到新矩阵 M1
    4. 若 M1 空且 r 中全为1,则算法结束,解为删除的 r 组成的集合;若 M1 空且 r 中不全为1,恢复与 r 相关的行和列,跳转步骤1;若 M1 不为空,跳转步骤1
  • 优化数据结构Dancing Link
    • 每次优先选择列元素个数最少的一列进行删除,这样能保证程序具有一定的启发性,使搜索树分支最少

应用

  • 将总集S中的所有数离散化,得到一个0-1矩阵模型M,每一行表示一个子集
  • 将问题转化为在二值矩阵中寻找一组行,这组行中每列有且只有一个1的问题
  • 精确覆盖问题和重复覆盖问题,建模时行表示决策、列表示状态条件,寻找一组决策,满足所有条件
#define IT(i, A, x) for(i=A[x]; i!=x; i=A[i])
const int M=1e5+5;
int ans, stk[M];
int n, m, idx, first[M], siz[M];//每行头节点、每列有几个元素
int L[M], R[M], U[M], D[M];//记录有效元素,左右上下
int col[M], row[M];//列行
void remove(const int &c)//通过标记假删除法删除第c列及相关行列
{
    //不改变c列和相关元素的自身的指向,而是改变相邻元素的指向
    int i, j;
    L[R[c]]=L[c];R[L[c]]=R[c];//删除第0行的辅助列数组
    IT(i, D, c)//删除c列有效元素有关行和列
        IT(j, R, i)
            U[D[j]]=U[j], D[U[j]]=D[j], --siz[col[j]];
}
void recover(const int &c)//恢复第c列及相关行列
{
    int i, j;
    IT(i, U, c)
        IT(j, L, i)
            U[D[j]]=D[U[j]]=j,++siz[col[j]];
    L[R[c]]=R[L[c]]=c;
}
void build(const int &r, const int &c)//建立n行m列的十字链表(无元素)
{
    n=r, m=c;
    for(int i=0; i<=c; ++i)
    {
        L[i]=i-1, R[i]=i+1;
        U[i]=D[i]=i;
    }
    L[0]=c, R[c]=0, idx=c;
    memset(first, 0, sizeof(first));
    memset(siz, 0, sizeof(siz));
}
void insert(const int &r, const int &c)//在第r行第c列插入元素(为“1”的元素)
{
    row[++idx]=r, col[idx]=c, ++siz[c];
    U[idx]=c, D[idx]=D[c], U[D[c]]=idx, D[c]=idx;
    if(!first[r])
        first[r]=L[idx]=R[idx]=idx;
    else
    {
        L[idx]=first[r], R[idx]=R[first[r]];
        L[R[first[r]]]=idx, R[first[r]]=idx;
    }
}
bool dance(int dep)//递归地删除和还原各个行列的过程
{
    int i, j, c=R[0];
    if(!R[0]){
        ans=dep;
        return 1;
    }
    IT(i, R, 0)
        if(siz[i]<siz[c]) c=i;//启发式删除
    remove(c);
    IT(i, D, c)
    {
        stk[dep]=row[i];//记录答案
        IT(j, R, i)remove(col[j]);
        if(dance(dep+1))return 1;
        IT(j, L, i)recover(col[j]);
    }
    recover(c);
    return 0;
}
如果觉得本文对您有帮助,可以支持下博主哦,感谢~
版权声明:除特殊说明外,博客文章均由 Sp1ke 原创,均采用 CC BY-SA 4.0 许可证
转载请注明文章地址及作者并附带本声明!
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇