Poj 1166 The Clocks(bfs)

题目链接:http://poj.org/problem?id=1166

思路分析:题目要求求出一个最短的操作序列来使所有的clock为0,所以使用bfs;

<1>被搜索结点的父子关系的组织:

在bfs中,队列中存储着解答树中搜索过的结点,并且每个结点都可以使用它在队列中的位置作为其唯一的ID;

另外,使用另一个数组存储结点的父节点和从父节点到该节点的操作,同样的,使用结点在队列中的位置作为该节点的ID;

这种方法类似于并查集的方法,使用多个线性数组来模拟树的结构;这里模拟解答树中搜索过的结点构成的树的结构;

<2>判重方法: 对于每个结点都有一个唯一的状态,使用位运算进行状态压缩和一个判重数组即可实现判重;

代码如下:

#include <queue>
#include <vector>
#include <iostream>
using namespace std;

const int mod = 0333333333; // 以0开头的数字代表八进制
const int MAX_N = (1 << 18) + 10;
int clock[9];
bool vis[mod];
int fa[MAX_N], path[MAX_N], state_queue[MAX_N], ans[MAX_N];
char mov[9][6] = {"ABDE", "ABC", "BCEF", "ADG", "BDEFH", "CFI", "DEGH", "GHI", "EFHI"};

int Bfs(int s)
{
    int start, head, tail;

    start = s;
    head = tail = 0;
    state_queue[tail++] = start;
    fa[0] = -1;
    vis[start] = true;

    while (head < tail)
    {
        int now = state_queue[head];

        for (int i = 0; i < 9; ++i)
        {
            int k = 0, value;
            int next = now;

            while (mov[i][k] != NULL)
            {
                value = mov[i][k] - 'A';
                next = next + (1 << (3 * value));
                next = next & mod;
                k++;
            }

            if (!vis[next])
            {
                fa[tail] = head;
                path[tail] = i + 1;

                if (next == 0)
                    return tail;
                else
                {
                    vis[next] = true;
                    state_queue[tail++] = next;
                }
            }
        }
        head++;
    }
    return -1;
}

void PrintPath(int k)
{
    int end = k, start = end;
    int len = 0;

    while (fa[start] != -1)
    {
        ans[len++] = path[start];
        start = fa[start];
    }

    for (int i = len - 1; i > 0; --i)
        printf("%d ", ans[i]);
    printf("%d
", ans[0]);
}

int main()
{
    int start, ans, temp = 0;

    start = 0;
    for (int i = 0; i < 9; ++i)
    {
        scanf("%d", &temp);
        start += temp << (3 * i);
    }
    
    ans = Bfs(start);   
    PrintPath(ans);
    return 0;
}
原文地址:https://www.cnblogs.com/tallisHe/p/4507459.html