hdu 1044 bfs dfs

来源:互联网 发布:gis开源软件 编辑:程序博客网 时间:2024/05/17 02:59

原帖地址:http://www.cnblogs.com/kuangbin/archive/2012/08/14/2637512.html

/*HDU 1044 Collect More Jewels走迷宫,问在规定时间内从起点到终点最多可以收集到宝物的价值是多少。先bfs找出所有宝物及起点和终点这些位置之间的最短距离,再起点dfs最大。加个剪枝,如果已经拿到所有宝物了,就不再搜索。AC G+ 31MS 560K*/#include<stdio.h>#include<iostream>#include<queue>#include<string.h>using namespace std;int W,H,L,M;//区域是H行W列的,L是时间限制,M是宝石的数量int val[60];//宝石的价值,1-Mchar map[60][60];bool used[60][60];//BFS时访问标记bool vis[60];//dfs时访问标记int step[60][60];int ans;//结果int sum;//所有的宝石的价值总和int move[4][2]={{-1,0},{1,0},{0,1},{0,-1}};int dis[60][60];//记录初始位置、各宝石和出口两两间的距离queue<int>q;//从(x1,y1)点到其它点的距离,s(0-M+1)是该点编号,0表示初始位置//M+1表示出口,1-M表示第i个宝物堆void bfs(int x1,int y1,int s){    while(!q.empty())q.pop();    memset(used,false,sizeof(used));    memset(step,0,sizeof(step));    int u=x1*W+y1;    q.push(u);    used[x1][y1]=true;    step[x1][y1]=0;    while(!q.empty())    {        u=q.front();        q.pop();        int x=u/W;        int y=u%W;        for(int i=0;i<4;i++)        {            int xx=x+move[i][0];            int yy=y+move[i][1];            if(xx<0||xx>=H||yy<0||yy>=W)continue;            if(used[xx][yy]||map[xx][yy]=='*')continue;            used[xx][yy]=true;            step[xx][yy]=step[x][y]+1;            if(map[xx][yy]=='@')dis[s][0]=step[xx][yy];            else if(map[xx][yy]=='<') dis[s][M+1]=step[xx][yy];            else if(map[xx][yy]>='A'&&map[xx][yy]<='J')                dis[s][map[xx][yy]-'A'+1]=step[xx][yy];            q.push(xx*W+yy);        }    }}//dfs,s表示当前点,value表示获得的价值,time表示花费的时间void dfs(int s,int value,int time){    if(time>L)return;//超出限制时间    if(ans==sum) return;//已经得到了最大的价值,剪枝(没有这个会超时)    if(s>M)    {        if(value>ans)ans=value;        return;    }    for(int i=0;i<=M+1;i++)    {        if(dis[s][i]==0||vis[i])continue;        vis[i]=true;        dfs(i,value+val[i],time+dis[s][i]);        vis[i]=false;    }}int main(){   // freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int T;    scanf("%d",&T);    int iCase=0;    while(T--)    {        memset(dis,0,sizeof(dis));        iCase++;        scanf("%d%d%d%d",&W,&H,&L,&M);        sum=0;        ans=-1;        for(int i=1;i<=M;i++)        {            scanf("%d",&val[i]);            sum+=val[i];        }        val[0]=val[M+1]=0;//这个很重要啊,WR到死啊        for(int i=0;i<H;i++)          scanf("%s",&map[i]);        for(int i=0;i<H;i++)          for(int j=0;j<W;j++)          {              if(map[i][j]=='@') bfs(i,j,0);              else if(map[i][j]=='<') bfs(i,j,M+1);              else if(map[i][j]>='A'&&map[i][j]<='J')                 bfs(i,j,map[i][j]-'A'+1);          }        memset(vis,false,sizeof(vis));        vis[0]=true;        dfs(0,0,0);        printf("Case %d:\n",iCase);        if(ans>=0)printf("The best score is %d.\n",ans);        else printf("Impossible\n");        if(T>0)printf("\n");    }    return 0;}


原创粉丝点击