2908

本文介绍了一种使用优先队列解决特定问题的方法,并对比了STL与自定义堆的性能差异。通过实例展示了如何利用优先队列进行状态搜索,以找到从初始状态到目标状态的最小代价路径。
/*
优先队列,注意直接用string速度比较慢,总之用STL比较慢
自己写堆,数据结构可能会比较快
*/

// include file
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <ctime>

#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <bitset>

#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <list>
#include <functional>

using namespace std;

// typedef
typedef long long ll;

// 
#define read freopen("in.txt","r",stdin)
#define write freopen("out.txt","w",stdout)

const double Pi = acos(-1.0);

#define TMIN(x,y) ( x<y?x:y )

#define DEBUG

// code begin
#define MAXN (1<<20)+1
int used[MAXN];
int T;
int L,Nop,Nw;
char op[40][22];
int opcost[40];
char from[22];
char to[22];

int hash(string s)
{
	int ans = 0;
	for(int i=0;i<L;i++)
	{
		ans = ans*2+s[i]-'0';
	}
	return ans;
}

int modify(int s,int k)
{
	int ans = 0;

	for(int i=0;i<L;i++)
	{
		bool t=s&(1<<(L-i-1));
		if( op[k][i]=='N')
		{
			;
		}
		else if(op[k][i]=='F')
		{
			t = 1-t;
		}
		else if(op[k][i]=='S')
		{
			t = 1;
		}
		else if(op[k][i]=='C')
		{
			t = 0;
		}
		ans = ans*2+t;

	}
	return ans;
}

struct Node
{
	Node(){}
	Node(int a,int b)
	{
		str=  a;
		time = b;
	}
	int str;
	int time;
};

struct cmp
{
	bool operator()(Node &a,Node &b)
	{
		return a.time>b.time;
	}
};

int main()
{
#ifdef DEBUG
	read;
	write;
#endif
	char in[22];
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d %d %d",&L,&Nop,&Nw);
		for(int i=0;i<Nop;i++)
		{
			scanf("%s %d",op[i],&opcost[i]);
		}

		for(int i=0;i<Nw;i++)
		{
			scanf("%s %s",from,to);
			//for(int j=0;j<MAXN;j++) used[j] = MAXN;
			memset(used,-1,sizeof(used));
			int first=hash(from);
			int end=hash(to);
			priority_queue<Node,vector< Node >, cmp> qps;
			qps.push( Node(first,0));
			used[ first] = 0;
			int ans = MAXN;
			while(!qps.empty())
			{
				Node cur = qps.top();qps.pop();
				
				if( cur.str==end )
				{
					ans = cur.time;
					break;
				}

				for(int k=0;k<Nop;k++)
				{
					int t2 = modify(cur.str,k);
					int vl = cur.time+opcost[k];
					if( used[t2]==-1 || vl<used[t2] )
					{
						used[t2] = vl;
						qps.push(Node(t2,vl));
					}
				}
			}

			if( ans==MAXN) printf("NP");
			else printf("%d",ans);
			if( i!=Nw-1) printf(" ");
			else printf("\n");
		}
	}
	return 0;
}

转载于:https://www.cnblogs.com/ac2012/archive/2011/05/28/2060708.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值