HDU - 3681 (bfs + dp + half pressed state)

Topic: the Click
meaning of the questions: Given an n * m map, D show where not to go, G supplement full of energy, has completed a minimum of energy and asked all the Y point from point F, take a consumption of a grid energy.
Note title given range, Y + G number of not more than 15. Find numerous paths in the best path, D can not go, the required number of points at most 16 (plus the point F), in fact, can be found deformation is essentially a TSP, the required points The three also. bfs process the shortest distance of each of two points, to create a new graph.
Directly after pressure-like dp, but we need to pay attention to the state of the property issue, taking the maximum or minimum state transition? Max is possible to take the value of the minimum path covered, is taken min max may not be ensured in this way. Half of the answer can be.

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define MAX_len 50100*4
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int MAXN=1e7+5;
int mo[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int n,m,state,fvis;
bool vis[20][20];
int mp[20][20];
int dp[20][(1<<18)];
int cnt=0;
struct A{
    int x,y;
}a[20];
struct B{
    int x,y;
    int di;
};
int dis[20][20];
void bfs(int t1,int t2)
{
    memset(vis,false,sizeof(vis));
    queue<B>hh;
    B temp;
    temp.di=0;
    temp.x=a[t1].x;
    temp.y=a[t1].y;
    hh.push(temp);
    while(!hh.empty())
    {
        temp=hh.front();
        for(int i=0;i<4;i++)
        {
            B tmp;
            tmp.x=temp.x+mo[i][0];
            tmp.y=temp.y+mo[i][1];
            if(tmp.x<0||tmp.x>n-1||tmp.y<0||tmp.y>m-1||vis[tmp.x][tmp.y]||mp[tmp.x][tmp.y]=='D')
                continue;
            vis[tmp.x][tmp.y]=true;
            tmp.di=temp.di+1;
            if(tmp.x==a[t2].x&&tmp.y==a[t2].y)
            {
                dis[t1][t2]=tmp.di;
                dis[t2][t1]=tmp.di;
                return ;
            }
            hh.push(tmp);
        }
        hh.pop();
    }
}
bool check(int res)
{
    int i,j,k;
    int yyyy=(1<<cnt);
    memset(dp,-1,sizeof(dp));
    dp[fvis][(1<<fvis)]=res;
    for(i=0;i<yyyy;i++)
    {
        for(j=0;j<cnt;j++)
        {
            if(dp[j][i]==-1||((1<<j)&i)==0)
                continue;
            if((state&i)==state&&dp[j][i]!=-1)
                return true;
            for(k=0;k<cnt;k++)
            {
                if(dis[j][k]==inf||((1<<k)&i)||k==j)
                    continue;
                if(dp[j][i]-dis[j][k]<0)
                {
                    continue;
                }
                int temp=i|(1<<k);
                if(mp[a[k].x][a[k].y]=='G')
                {
                    dp[k][temp]=res;
                    continue;
                }
                dp[k][temp]=max(dp[k][temp],dp[j][i]-dis[j][k]);
            }
        }
    }
    return false;
}
int main()
{
    while(~scanf("%d %d",&n,&m)&&(n||m))
    {
        getchar();
        state=0;
        int i,j,k;
        cnt=0;
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
               scanf("%c",&mp[i][j]);
                if(mp[i][j]=='F'||mp[i][j]=='G'||mp[i][j]=='Y')
                {
                    if(mp[i][j]=='F')
                        fvis=cnt;
                    if(mp[i][j]=='F'||mp[i][j]=='Y')
                        state+=(1<<cnt);
                    a[cnt].x=i;
                    a[cnt++].y=j;
                    continue;
                }
            }
            getchar();
        }
        memset(dis,inf,sizeof(dis));
        for(i=0;i<cnt;i++)
        {
            for(j=0;j<cnt;j++)
            {
                if(i==j)
                    dis[i][j]=0;
                else
                    bfs(i,j);
            }
        }
        int ans=-1;
        int l=0,r=250;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(check(mid))
            {
                ans=mid;
                r=mid-1;
            }
            else
                l=mid+1;
        }
        printf("%d\n",ans);
    }
    return 0;
}
Published 72 original articles · won praise 19 · views 7491

Guess you like

Origin blog.csdn.net/weixin_43958964/article/details/105212141