HDU 1044 BFS + DFS

41 篇文章 0 订阅

分别用dfs, bfs做了一次

dfs超时,bfs超内存


题目意思  求解是否能够到达出口 如果能 求解到达时的最大携带价值
首先使用广搜搜出包括起点和终点在内 所有特殊点之间的最短距离 建立一个隐式图
然后使用DFS枚举各个组合 然后求出最大值 注意DFS的强剪


代码思想很好,但是代码风格让人看起来难受,改了半天还是这个样子,下次重写。

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

long value[20];
long Step[20][20];
char Map[60][60];
long W,H,L,M;
int stx, sty;

typedef struct
{
	long mi,mj;
	long step;
	long from;
}Node;

queue<Node> q;

bool hs[60][60][20];
long dx[]={0,1,-1,0};
long dy[]={1,0,0,-1};


long b;

inline void BFS()
{
	while (!q.empty())
	{
		q.pop();
	}
	memset(hs,0,sizeof(hs));

	Node point;
	point.mi = stx;
	point.mj = sty;
	point.from = 0;
	point.step = 0;
	q.push(point);
	hs[point.mi][point.mj][point.from]=true;


	while (!q.empty())
	{
		Node cur=q.front();
		q.pop();

		long j;
		Node next;

		for (j=0;j<4;++j)
		{
			next.mi=cur.mi+dx[j];
			next.mj=cur.mj+dy[j];
			next.step=cur.step+1;
			next.from=cur.from;
			if (next.mi>=0&&next.mi<H&&next.mj>=0&&next.mj<W)
			{
				if (next.step<=L&&!hs[next.mi][next.mj][next.from]&&Map[next.mi][next.mj]!='*')
				{
					hs[next.mi][next.mj][next.from]=true;
					q.push(next);

					if (Map[next.mi][next.mj]>='A'&&Map[next.mi][next.mj]<='J')
					{
						Step[next.from][Map[next.mi][next.mj]-'A'+2]=Step[Map[next.mi][next.mj]-'A'+2][next.from]=next.step;
						next.from=Map[next.mi][next.mj]-'A'+2;
						next.step=0;
						hs[next.mi][next.mj][next.from]=true;
						q.push(next);    
					}                
					else if (Map[next.mi][next.mj]=='@')
					{
						Step[next.from][0]=Step[0][next.from]=next.step;
						next.from=0;
						next.step=0;
						hs[next.mi][next.mj][next.from]=true;
						q.push(next);    
					}
					else if (Map[next.mi][next.mj]=='<')
					{
						Step[next.from][1]=Step[1][next.from]=next.step;
						next.from=1;
						next.step=0;
						hs[next.mi][next.mj][next.from]=true;
						q.push(next);    
					}
				}
			}

		}
	}
}

bool vist[20];
long lmax;
long all;

inline void dfs(long pos,long now,long step)
{
	if (lmax==all||step>L)
	{
		return;
	}
	if (Step[pos][1]!=-1&&step+Step[pos][1]<=L&&now>lmax)
	{
		lmax=now;
	}
	long i;
	for (i=2;i<M+2;++i)
	{
		if (!vist[i]&&Step[pos][i]!=-1)
		{
			vist[i]=true;
			dfs(i,now+value[i],step+Step[pos][i]);
			vist[i]=false;
		}
	}
}


int main()
{
	long T;
	scanf("%ld",&T);
	b=1;
	while (T--)
	{
		scanf("%ld%ld%ld%ld",&W,&H,&L,&M);
		long i,j;
		all=0;
		for (i=2;i<M+2;++i)
		{
			scanf("%ld",&value[i]);
			all+=value[i];
		}
		value[0]=value[1]=0;

		gets(Map[0]);
		for (i=0;i<H;++i)
		{
			gets(Map[i]);
			for (j=0;j<W;++j)
			{
				if (Map[i][j]=='@')
				{
					stx = i;
					sty = j;
				}
			}
		}

		memset(Step,-1,sizeof(Step));
		BFS();
		if (b!=1)
			puts("");
		printf("Case %ld:\n",b++);

		if (Step[0][1]==-1||Step[0][1]>L)
		{
			puts("Impossible");
			continue;
		}
		memset(vist,0,sizeof(vist));
		lmax=-1;
		vist[0]=true;
		dfs(0,0,0);
		if (lmax!=-1)
			printf("The best score is %ld.\n",lmax);
		else
			puts("Impossible");                
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值