POJ 1137 The New Villa

127 篇文章 0 订阅
7 篇文章 0 订阅

/*

复杂BFS

参考了网上别人的程序

POJ 上需要SJ,为了避免这个所以需要对输入进行排序*/

 

#include <iostream>
#include <queue>
#include <algorithm>
#define MAX_S 1024
#define MAX_H 10
using namespace std;

struct statusN
{
    int rNum, bit, step;
    statusN *next;
}status[MAX_H + 2][MAX_S + 2];

struct doorN
{
    int f, t;
    int getOpp(int curS) //-1 not exist
    {
        if(curS == f) return t;
        else if(curS == t) return f;
        else return -1;
    }
}door[MAX_H * MAX_H + 2];

struct controlN
{
    int hNum, lNum;
}control[MAX_H * MAX_H + 2];

int v[MAX_H + 2][MAX_S + 2];
int exp[MAX_H + 2];
int roomNum, doorNum, switNum;

int getLight(int ex)
{
    for(int i = 0; i < roomNum; i++)
        if(exp[i] == ex)
            return i;
    return -1;
}


void print(statusN *cur)
{
    if(!cur->next)
        return;
    print(cur->next);
   
    int bitT = cur->bit, bitF = cur->next->bit, room2 = cur->rNum, room1 = cur->next->rNum;
    if(bitT == bitF)
        cout<<"- Move to room "<<room2+1<<"."<<endl;
    else
    {
        int ex = bitF ^ bitT;
        int which = getLight(ex);
        if(ex & bitT)
            cout<<"- Switch on light in room "<<getLight(ex) + 1<<"."<<endl;
        else
            cout<<"- Switch off light in room "<<getLight(ex) + 1<<"."<<endl;
    }
}

bool solve()
{
    memset(v, 0, sizeof(v));
    statusN *final = &status[0][exp[0]];
    final->next = NULL;
    final->step = 0;   
   
    queue<statusN *> Q;
    v[0][exp[0]] = true;
    Q.push(final);
    bool finish = false;
    statusN *cur;

    int i;
    while(!Q.empty())
    {
        cur = Q.front();
        Q.pop();

        int bit = cur->bit, room = cur->rNum, step = cur->step;

        if(bit == exp[roomNum - 1] && room == roomNum - 1)
        {
            finish = true;
            break;
        }

        for(i = 0; i < doorNum; i++)
        {
            int opp;
            if((opp = door[i].getOpp(room)) != -1 && (bit & exp[opp]) > 0 && (!v[opp][bit]))
            {
                v[opp][bit] = 1;
                statusN *ns = &status[opp][bit];
                ns->next = cur;
                ns->step = step + 1;
                Q.push(ns);
            }
        }
        for(i = 0; i < switNum; i++)
        {
            int ctrlNum = control[i].lNum;
            if(control[i].hNum == room)
            {
                int newBit = bit ^ exp[ctrlNum];
                if(v[room][newBit])
                    continue;
                v[room][newBit] = 1;
                statusN *ns = &status[room][newBit];
                ns->next = cur;
                ns->step = step + 1;
                Q.push(ns);
            }
        }
    }
    if(!finish)
        return false;
    cout<<"The problem can be solved in "<<cur->step<<" steps:"<<endl;
    cur = &status[roomNum - 1][exp[roomNum - 1]];
    print(cur);
    return true;   
}

bool compare(controlN c1, controlN c2)
{
    if(c1.hNum < c2.hNum)
        return true;
    else if(c1.hNum == c2.hNum)
    {
        if(c1.lNum <= c2.lNum)
            return true;
        return false;
    }
    return false;
}


int main()
{
    int i, j, f, t;
    exp[0] = 1;
    for(i = 1; i <= MAX_H; i++)
        exp[i] = exp[i - 1]<<1;

    for(i = 0; i < MAX_H; i++)
    {
        for(j = 0; j < MAX_S; j++)
        {
            statusN cur = {i, j, 0, NULL};
            status[i][j] = cur;
        }
    }
    int caseN = 0;
    while(cin>>roomNum>>doorNum>>switNum && (roomNum + doorNum + switNum) != 0)
    {
        caseN++;
        for(i = 0; i < doorNum; i++)
        {
            cin>>f>>t;
            doorN cur = {f - 1, t - 1};
            door[i] = cur;
        }
        for(i = 0; i < switNum; i++)
        {
            cin>>f>>t;
            if(f == t)
            {
                switNum--;
                i--;
                continue;
            }
            controlN cur = {f - 1, t - 1};
            control[i] = cur;
        }
        cout<<"Villa #"<<caseN<<endl;
        sort(control, control + switNum, compare);
        if (!solve()) cout<<"The problem cannot be solved."<<endl;
        cout<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值