首页 > 代码库 > 1044BFS+DFS

1044BFS+DFS

/*
	HDOJ1044 BFS+DFS
	把起点@,终点<,各个分值点A~J 作为目标点,分别对各个点DFS得到各个点对的最近距离
	
	再用BFS,从起点到终点,经过各个分值点在时间限制内所能得到的最优值
	
	遗留问题一:
		说好的用Floyd代替BFS求最优值自己实现不出来。。。。
	遗留问题二:
		为啥  用   dist[0][k+1]>t 作为终止条件就是错的 !!!!求大神指教 
*/

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <sstream>
#include <queue>
#include <stack>
using namespace std;

#define input freopen("input.txt","r",stdin)
#define output freopen("output.txt","w",stdout)
#define For1(i,a,b) for (i=a;i<b;i++)
#define For2(i,a,b) for (i=a;i<=b;i++)
#define Dec(i,a,b) for (i=a;i>b;i--)
#define Dec2(i,a,b) for (i=a;i>=b;i--)
#define Sca_d(x) scanf("%d",&x)
#define Sca_s(x) scanf("%s",x)
#define Sca_c(x) scanf("%c",&x)
#define Sca_f(x) scanf("%f",&x)
#define Sca_lf(x) scanf("%lf",&x)
#define Fill(x,a) memset(x,a,sizeof(x))
#define MAXN 0x7fffffff

int n,m,k;
int score[150];
int dist[200][200];
char Map[550][550],in[550];
int dir_x[]={0,1,-1,0,0};
int dir_y[]={0,0,0,1,-1};
int vis[55],sum,ans,t;

void bfs(int tx,int ty,int num)
{
	int head=1,tail=1,dir,nx,ny;
	int steps[55][55],visit[55][55];
	struct
	{
		int x,y;
	}que[2555];
	Fill(steps,0);Fill(visit,0);Fill(que,0);
	que[head].x=tx;
	que[head].y=ty;
	visit[tx][ty]=1;
	while(head<=tail)
	{
		For2(dir,1,4)
		{
			nx=que[head].x+dir_x[dir],ny=que[head].y+dir_y[dir];
			if (nx>=0&&nx<n&&ny>=0&&ny<m&&!visit[nx][ny]&&Map[nx][ny]!='*')
			{
				steps[nx][ny]=steps[que[head].x][que[head].y]+1;
				tail++;
				que[tail].x=nx;
				que[tail].y=ny;
				visit[nx][ny]=1;
				if (Map[nx][ny]>='A'&&Map[nx][ny]<='J')
					dist[num][Map[nx][ny]-'A'+1]=steps[nx][ny];
				else if (Map[nx][ny]=='@')
					dist[num][0]=steps[nx][ny];
				else if (Map[nx][ny]=='<')
					dist[num][k+1]=steps[nx][ny];
			}
		}
		head++;
	}
}

void dfs(int s,int value,int time)
{
	int i;
    if(time>t) return;//超出限制时间
    if(ans==sum) return;//已经得到了最大的价值,剪枝(没有这个会超时)
						//借鉴的kuangbin大神的高级思路! 
    if(s==k+1)
    {
        if(value>ans) ans=value;
        return;
    }
    For2(i,1,k+1)
    {
        if(dist[s][i]==0||vis[i]) continue;
        vis[i]=true;
        dfs(i,value+score[i],time+dist[s][i]);
        vis[i]=false;
    }
}

int main()
{
	//input;
	int i,j,Case;
	cin>>Case;
	for(int Case_num=1;Case_num<=Case;Case_num++)
	{
		getchar();
		Fill(score,0);Fill(dist,0);Fill(score,0);Fill(Map,0);Fill(vis,0);sum=0,ans=-1;
		//一切有用的东西赋初值! 
		cin>>m>>n>>t>>k;
		For2(i,1,k) Sca_d(score[i]),sum+=score[i];//输入分值的和时,顺便计算所有分值的和。方便剪枝 
		For2(i,0,n-1)
		{
			Sca_s(in);
			For2(j,0,m-1)
				Map[i][j]=in[j];
		}
		For2(i,0,n-1)
			For2(j,0,m-1)
				if ((Map[i][j]>='A'&&Map[i][j]<='J')) 
					bfs(i,j,Map[i][j]-'A'+1);//A表示为1,依次类推 
				else if (Map[i][j]=='@')
					bfs(i,j,0);//起点标号为0
		/*For2(i,0,k)
		{
			For2(j,0,k+1)
				printf("%d ",dist[i][j]);
			cout<<endl;
		}
		cout<<endl;*/
		//写DFS为了检验BFS的正确性作的中间过程输出 
		printf("Case %d:\n",Case_num);
		
		dfs(0,0,0);
		if (ans>=0) printf("The best score is %d.\n",ans);
		else printf("Impossible\n");
		
		/*if (dist[0][k+1]>t) printf("Impossible\n");
		//不理解用  dist[0][k+1]   作为判断条件为啥WA!!!! 
		else
		{
			dfs(0,0,0);
			printf("The best score is %d.\n",ans);
		}*/
		if (Case_num<Case) cout<<endl;
	}
	return 0;
}
		//ans=dfs(startx,starty);
			/*For2(i,1,k+1)
				if (dist[0][i]&&dist[0][i]<=t)
					dp[i]=score[i],dp_dis[i]=dist[0][i];
			int kk=0;
			For2(kk,0,k+1)
			For2(i,0,k+1)
				if (dist[kk][i])
					For2(j,0,k+1)
						if (dist[i][j])
							if (dist[kk][i]+dist[i][j]<=t)
							{
								if (dp[i]+dp[j]>=dp[j])
									dp[j]=dp[i]+dp[j],dp_dis[j]=dist[kk][i]+dist[i][j];
								else if (dp[j]==dp[i]+dp[j]&&dp_dis[j]<dist[kk][i]+dist[i][j])
									dp_dis[j]=dist[kk][i]+dist[i][j];
							}*/
		/*For2(i,0,k+1)
		{
			For2(j,0,k+1)
				printf("%d ",dist[i][j]);
			cout<<endl;
		}
		cout<<endl;*/
//这里是自己想实现的Floyd求最优值,总是WA。。。。 

1044BFS+DFS