zoukankan      html  css  js  c++  java
  • hdu-4856 Tunnels 状压DP

    http://acm.hdu.edu.cn/showproblem.php?pid=4856

    有若干管道,每个管道有且只能走一次,而地图可以随意走。

    那么可以先处理每个管道间的最短路(不要考虑借助其他管道的情况,因为随后我们用压位的方式可以很轻松地处理不走重复管道的问题,这里不应该引入过多干扰)。

    随后我们把每个管道是否访问看作01序列,dp[i][j]看着当前处于j号管道,访问状态为i。然后预先加入当且访问一个管道的m个状态,做bfs即可(很多人做了三重循环,个人不太会那么犀利的操作,只会bfs直观一点hhh,不过两个bfs搞得代码很丑就是了)。

    #include <iostream>
    #include <string>
    #include <queue>
    #include <cstring>
    using namespace std;
    const int N=1005;
    const int inf=99999999;
    int n,m;
    string mp[20];
    int vis[20][20];
    struct p
    {
        int x,y;
    };
    p in[20],ou[20];
    int d[20][20];
    struct node
    {
        int s;
        p po;
    };
    int dir[4][2]={1,0,-1,0,0,1,0,-1};
    bool ok(p px)
    {
        if(px.x<0||px.y<0)return 0;
        if(px.x>=n||px.y>=n)return 0;
        if(vis[px.y][px.x]) return 0;
        if(mp[px.y][px.x]=='#')return 0;
        return 1;
    }
    void bfs(int np)
    {
        queue<node> q;
        node ii;
        ii.s=0;
        ii.po=ou[np];
        q.push(ii);
        memset(vis,0,sizeof vis);
        vis[ii.po.y][ii.po.x]=1;
        d[np][np]=0;
        while(!q.empty())
        {
            node now=q.front();
            q.pop();
            for(int i=0;i<m;i++)
            {
                if(i==np)continue;
                if(now.po.x==in[i].x&&now.po.y==in[i].y)
                    d[np][i]=now.s;
            }
            for(int i=0;i<4;i++)
            {
                node nx=now;
                nx.s++;
                nx.po.x+=dir[i][0];
                nx.po.y+=dir[i][1];
                if(ok(nx.po))
                {
                    vis[nx.po.y][nx.po.x]=1;
                    q.push(nx);
                }
            }
        }
    }
    int dp[40000][20];
    int numid[20];
    struct dpx
    {
        int d;
        int po;
        dpx(int dd,int pp)
        {
            d=dd;
            po=pp;
        }
    };
    int main()
    {
        cin.sync_with_stdio(false);
        while(cin>>n>>m)
        {
            for(int i=0;i<n;i++)
                cin>>mp[i];
            for(int i=0;i<m;i++)
            {
                cin>>in[i].y>>in[i].x>>ou[i].y>>ou[i].x;
                in[i].x--;
                in[i].y--;
                ou[i].x--;
                ou[i].y--;
            }
            for(int i=0;i<m;i++)
                for(int j=0;j<m;j++)
                    d[i][j]=inf;
            for(int i=0;i<m;i++)
                bfs(i);
            for(int i=0;i<(1<<m);i++)
                for(int j=0;j<m;j++)
                    dp[i][j]=inf;
            int dx=1;
            queue<dpx> q;
            int ad=0;
            for(int i=0;i<m;i++)
            {
                ad+=dx;
                dp[dx][i]=0;
                numid[i]=dx;
                q.push(dpx(dx,i));
                dx<<=1;
            }
            while(!q.empty())
            {
                dpx now=q.front();
                q.pop();
                for(int i=0;i<m;i++)
                {
                    if((now.d&numid[i])==0)
                    {
                        dpx nx=now;
                        nx.d+=numid[i];
                        nx.po=i;
                        if(dp[nx.d][nx.po]>dp[now.d][now.po]+d[now.po][nx.po])
                        {
                            dp[nx.d][nx.po]=dp[now.d][now.po]+d[now.po][nx.po];
                            q.push(nx);
                        }
                    }
                }
            }
            int ans=inf;
            for(int i=0;i<m;i++)
                ans=min(ans,dp[(1<<m)-1][i]);
            if(ans>=inf)cout<<-1<<endl;
            else
                cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Altium Designer 20下载与安装教程
    推荐一些好用的Chrome插件
    记录生活——三款优秀云笔记的搭配使用
    Sublime Text3的安装以及python开发环境的搭建
    Altium Designer 只导出PCB元器件及标号的PDF文件的方法
    Altium Designer 编译原理图出现has no driving source警告解决办法
    Altium Designer 16 如何分别导出TOP层和BOTTOM层
    HTML学习记录和总结
    AD16/MDK5/CAD2019及2007/Dev-C++/Office2016专业版软件安装包
    Keil5调试过程中遇到的一些警告和错误
  • 原文地址:https://www.cnblogs.com/LukeStepByStep/p/8351404.html
Copyright © 2011-2022 走看看