/* 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。。。。
原文地址:http://blog.csdn.net/kevin66654/article/details/41595677