zoukankan      html  css  js  c++  java
  • POJ 2908 Quantum (bfs+优先队列)

    题意:给定m个操作和这几种操作所花费的能量,操作的长度n,如果源串能过经过这几种操作转化为目的串,问最多消耗多少能量。

    思路:最短路径,也就是bfs+优先队列,不过在记录入队后的元素时要注意,进入队列的元素有可能在进入队列,因为多路径嘛,也就是说,根据最短路径的思想,要及时更新入队的元素,我用的是STL中的priority_queue来操作的,用堆应该快一些吧,记录状态的时候可以根据位运算来实现,减少内存和时间。

    #include <iostream>
    #include
    <cstdio>
    #include
    <algorithm>
    #include
    <memory.h>
    #include
    <cmath>
    #include
    <set>
    #include
    <queue>
    #include
    <vector>
    using namespace std;

    const int BORDER = (1<<20)-1;
    #define MAXN 50
    #define INF 0x7ffffff
    #define CLR(x,y) memset(x,y,sizeof(x))
    #define ADD(x) ((++x)&BORDER)
    #define IN(x) scanf("%d",&x)
    #define OUT(x) printf("%d\n",x)
    #define MIN(m,v) (m)<(v)?(m):(v)
    #define MAX(m,v) (m)>(v)?(m):(v)
    #define ABS(x) (x>0?x:-x)

    struct NODE{
    int val;
    int step;
    }node,t_node;
    bool operator<(const NODE& a,const NODE& b)
    {
    return a.step>b.step;
    }
    priority_queue
    <NODE> que;
    int tt,n,m,n_word,mmin;
    int dist[1<<22],op[MAXN][MAXN],cost[MAXN],origin[MAXN],target[MAXN];
    int ans[MAXN];
    int init()
    {
    CLR(dist,
    127);
    CLR(origin,
    0);
    CLR(target,
    0);
    CLR(ans,
    -1);
    return 0;
    }
    int input()
    {
    int i,j,tmp;
    char str[MAXN];
    scanf(
    "%d%d%d",&n,&m,&n_word);
    for(i = 0; i < m; ++i)
    {
    scanf(
    "%s %d",str,&cost[i]);
    for(j = 0; j < n; ++j)
    {
    switch(str[j])
    {
    case 'N': op[i][j] = 0; break;
    case 'F': op[i][j] = 1; break;
    case 'S': op[i][j] = 2; break;
    case 'C': op[i][j] = 4; break;
    }
    }
    }
    for(i = 0; i < n_word; ++i)
    {
    scanf(
    "%s",str);
    for(j = 0; j < n; ++j)
    if(str[j] == '1')
    origin[i]
    |= (1<<n-j-1);
    scanf(
    "%s",str);
    for(j = 0; j < n; ++j)
    if(str[j] == '1')
    target[i]
    |= (1<<n-j-1);
    }
    return 0;
    }
    int bfs(const int& index)
    {
    int i,j,tmp,val,oper,k;
    /* empty the queue */
    while(!que.empty())
    que.pop();
    /* init queue */
    node.val
    = origin[index];
    node.step
    = 0;
    que.push(node);
    mmin
    = INF;
    /* while loop */
    while(!que.empty())
    {
    node
    = que.top();
    que.pop();
    val
    = node.val;
    if(val == target[index])
    {
    mmin
    = MIN(mmin,node.step);
    break;
    }
    for(i = 0; i < m; ++i)
    {
    tmp
    = val;
    for(j = 0; j < n; ++j)
    {
    oper
    = op[i][j];
    k
    = n-j-1;
    if(oper&1)
    tmp
    = tmp^(1<<k);
    else if(oper&2)
    tmp
    = tmp|(1<<k);
    else if(oper&4)
    tmp
    = tmp&(~(1<<k));
    }
    if(dist[tmp] > node.step+cost[i])
    {
    dist[tmp]
    = node.step+cost[i];
    t_node.val
    = tmp;
    t_node.step
    = node.step+cost[i];
    que.push(t_node);
    }
    }
    }
    if(mmin != INF)
    ans[index]
    = mmin;
    return 0;
    }
    int output()
    {
    int i,j,tmp;
    for(i = 0; i < n_word; ++i)
    {
    if(i == 0)
    {
    if(ans[0] == -1)
    printf(
    "NP");
    else
    printf(
    "%d",ans[0]);
    continue;
    }
    if(ans[i] == -1)
    printf(
    " NP");
    else
    printf(
    " %d",ans[i]);
    }
    printf(
    "\n");
    return 0;
    }

    int main()
    {
    int i,j,tmp;
    IN(tt);
    while(tt--)
    {
    init();
    input();
    for(i = 0; i < n_word; ++i)
    {
    CLR(dist,
    127);
    bfs(i);
    }
    output();
    }
    return 0;
    }
  • 相关阅读:
    推荐vue脚手架工具 vue-cli
    React仿大众点评外卖app
    推荐一个react脚手架工具
    eclipse 中配置php的 XDebug调试
    再谈extjs4.1中gridpanel动态表头动态列
    控制extsj4.1 gridpanel表格行或者单元格的编辑
    windows8.1 app所有默认样式
    windows8.1 app样式定义使用
    windows8.1 app入门开发学习
    Silverlight Tools 语言不匹配问题
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1704757.html
Copyright © 2011-2022 走看看