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 ;
}

你可能感兴趣的:(quantum)