zoukankan      html  css  js  c++  java
  • BZOJ2595 Wc2008 游览计划 【斯坦纳树】【状压DP】*

    BZOJ2595 Wc2008 游览计划


    Description

    这里写图片描述
    这里写图片描述

    Input

    第一行有两个整数,N和 M,描述方块的数目。
    接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个景点;
    否则表示控制该方块至少需要的志愿者数目。 相邻的整数用 (若干个) 空格隔开,
    行首行末也可能有多余的空格。

    Output

    由 N + 1行组成。第一行为一个整数,表示你所给出的方案中安排的志愿者总数目。
    接下来 N行,每行M 个字符,描述方案中相应方块的情况:
    z ‘_’(下划线)表示该方块没有安排志愿者;
    z ‘o’(小写英文字母o)表示该方块安排了志愿者;
    z ‘x’(小写英文字母x)表示该方块是一个景点;
    注:请注意输出格式要求,如果缺少某一行或者某一行的字符数目和要求不
    一致(任何一行中,多余的空格都不允许出现) ,都可能导致该测试点不得分。

    Sample Input

    4 4
    0 1 1 0
    2 5 5 1
    1 5 5 1
    0 1 1 0

    Sample Output

    6
    xoox
    ___o
    ___o
    xoox

    HINT

    对于100%的数据,N,M,K≤10,其中K为景点的数目。输入的所有整数均在[0,2^16]的范围内


    斯坦纳树,状压DP记录路径
    还有一点小小的不同,就是这道题用子集信息进行更新的时候我们需要减去当前点的权值一次,因为两个子集都包含了这个点,权值多算了一次

    有关斯坦纳树的总结,请看
    https://www.cnblogs.com/dream-maker-yk/p/9676340.html


    #include<bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define N 11
    struct Node{int x,y,s;};
    int mx[]={0,0,1,-1};
    int my[]={1,-1,0,0};
    int n,m,maxs;
    int cost[N][N],st[N][N],vis[N][N],cnt;
    int d[N][N][1<<N];
    Node pre[N][N][1<<N];
    bool in[N][N][1<<N];
    queue<Node> Q;
    void SPFA(){
        while(!Q.empty()){
            Node t=Q.front();Q.pop();
            int x=t.x,y=t.y,s=t.s;
            in[x][y][s]=0;
            for(int i=0;i<4;i++){
                int tx=x+mx[i],ty=y+my[i],ts=s|st[tx][ty];
                if(tx<1||tx>n||ty<1||ty>m)continue;
                if(d[tx][ty][ts]>d[x][y][s]+cost[tx][ty]){
                    d[tx][ty][ts]=d[x][y][s]+cost[tx][ty];
                    pre[tx][ty][ts]=t;
                    if(!in[tx][ty][ts]&&s==ts){
                        in[tx][ty][ts]=1;
                        Q.push((Node){tx,ty,ts});
                    }
                }
            }
    
        }
    }
    void dfs(int x,int y,int s){
        vis[x][y]=1;
        Node t=pre[x][y][s];
        int tx=t.x,ty=t.y,ts=t.s;
        if(!tx&&!ty&&!ts)return;
        dfs(tx,ty,ts);
        if(x==tx&&y==ty)dfs(x,y,(s-ts)|st[x][y]);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                scanf("%d",&cost[i][j]);
                if(!cost[i][j])st[i][j]=1<<(cnt++);
            }
        maxs=(1<<cnt)-1;
        memset(d,0x3f,sizeof(d));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(st[i][j])d[i][j][st[i][j]]=0;
        for(int k=0;k<=maxs;k++){
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++){
                    if(st[i][j]&&!(st[i][j]&k))continue;
                    for(int x=(k-1)&k;x;x=(x-1)&k){
                        int t=d[i][j][x|st[i][j]]+d[i][j][(k-x)|st[i][j]]-cost[i][j];
                        if(t<d[i][j][k]){
                            d[i][j][k]=t;
                            pre[i][j][k]=(Node){i,j,x|st[i][j]};
                        }
                    }
                    if(d[i][j][k]<INF){
                        Q.push((Node){i,j,k});
                        in[i][j][k]=1;
                    }
                }
            SPFA();
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)if(st[i][j]){
                printf("%d
    ",d[i][j][maxs]);
                dfs(i,j,maxs);
                for(int x=1;x<=n;x++){
                    for(int y=1;y<=m;y++){
                        if(st[x][y])putchar('x');
                        else if(vis[x][y])putchar('o');
                        else putchar('_');
                    }
                    putchar('
    ');
                }
                return 0;
            }
        return 0;
    }
  • 相关阅读:
    转载:从git仓库中删除不必要的文件
    问题:Swiper父容器隐藏时实例化组件,组件滑动失效
    图片预加载
    移动端苹果手机:图片没有加载完成前,白色边框线是怎么来的
    bower 安装依赖提示 EINVRES Request to https://bower.herokuapp.com/packages/xxx failed with 502
    H5序列帧播放
    盟军敢死队
    二维游戏开发的点滴
    用c语言开发游戏 快乐的痛 笑着哭
    ibatis
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9676341.html
Copyright © 2011-2022 走看看