zoukankan      html  css  js  c++  java
  • 贪吃蛇(bzoj 4213)

    Description

     最近lwher迷上了贪吃蛇游戏,在玩了几天却从未占满全地图的情况下,他不得不承认自己是一个弱菜,只能改去开发一款更弱的贪吃蛇游戏。
    在开发的过程中,lwher脑洞大开,搞了一个多条蛇的模式。但由于这种模式太难操作,于是他只好改变游戏的玩法,稍微变化一下游戏目标。
    新的游戏是这样的:
    一些蛇覆盖了一个网格。每个格子要么是一个障碍物,要么是蛇的一部分。每条蛇占据了一条折线(拐角处只能水平和竖直连接),且只是占据两个格子。蛇与蛇之间不能重叠,蛇也不会与自己重叠。每条蛇还必须满足以下两个条件中的一个:
         1、两个端点所在的格子在网格的边界。
         2、蛇构成一个环,即两个端点相邻(垂直或水平,不能斜着),至少要占据4个格子(否则没法形成环)。
    给定一个网格,用r x c的字符矩阵描述:‘#’代表障碍物,‘.’代表空地。在满足前面所述的条件下覆盖所有空地,并使得端点在网格边界(即不构成环)的蛇尽量少。(如果一条蛇既构成环,又是端点在边界,那么不计入答案)
         例如,以下网格:
     
     
     
    可以由下面三种方案覆盖。还有其他的方案,但是没法仅用一条不构成环的蛇就覆盖整个网络的方案。
     
     
     
    给定一个网络的描述,输出最少需要多少条不构成环的蛇来覆盖这个网格。如果不存在能够覆盖网格的方案,输出-1。

    Input

    一个字符矩阵,行数和列数不超过12。输入文件中没有多余的空白字符,每行之后都有换行符。

    Output

    输出满足题目要求的那个整数。
     

    Sample Input

    ......
    .#.##.
    .#....
    ....#.
    .##.#.
    ......

    Sample Output

    2
    /*
        上下界费用流,建图很诡异。
        考虑一条不构成环的蛇,除了头尾之外的点,每个点都与两个点相连。 
        而环形蛇则所有点都与两个点相连。 
        所以我们对矩阵黑白染色.建立源点s,汇点t。 
        s向所有白点连容量为2,费用为0的边,表示这个点需要与两个点相连。 
        所有黑点向t连容量为2,费用为0的边,表示两个点需要与这个点相连。 
        这里的容量为2是指容量必须为2,需要上下界来限定。 
        每个白点向周围的黑点连容量为1,费用为0的边,表示这个点可以和周围的点形成蛇。 
        这里的容量并不要求一定是1,不需要用上下界来限定。 
        每个边界上的白点向t连容量为1,费用为1的边,表示形成了一条不成环的蛇。 
        s向每个边界上的黑点连容量为1,费用为1的边,表示形成了一条不成环的蛇。 
        然后用有源有汇有上下界的费用流处理即可。 
        注意每条蛇会在头和尾各算一次,所以最后答案需要除2。 
        (题解源于:http://blog.csdn.net/sunshinezff/article/details/51824068*/
    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<cstring>
    #define N 310
    #define inf 1000000000
    using namespace std;
    int head[N],dis[N],inq[N],fa[N],d[N],n,m,cnt=1,SS,TT,S,T,ans;
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    struct node{int v,f,w,pre;}e[N*10];
    char ch[N][N];
    queue<int> q;
    void add(int u,int v,int f,int w){
        e[++cnt].v=v;e[cnt].f=f;e[cnt].w=w;e[cnt].pre=head[u];head[u]=cnt;
        e[++cnt].v=u;e[cnt].f=0;e[cnt].w=-w;e[cnt].pre=head[v];head[v]=cnt;
    }
    bool spfa(){
        for(int i=0;i<=T;i++) dis[i]=inf;
        q.push(S);dis[S]=0;
        while(!q.empty()){
            int u=q.front();q.pop();inq[u]=0;
            for(int i=head[u];i;i=e[i].pre)
                if(e[i].f&&dis[e[i].v]>dis[u]+e[i].w){
                    dis[e[i].v]=dis[u]+e[i].w;
                    fa[e[i].v]=i;
                    if(!inq[e[i].v]){
                        q.push(e[i].v);
                        inq[e[i].v]=1;
                    }
                }
        }
        return dis[T]!=inf;
    }
    void updata(){
        int i=fa[T],x=inf;
        while(i){
            x=min(x,e[i].f);
            i=fa[e[i^1].v];
        }
        i=fa[T];
        while(i){
            e[i].f-=x;
            e[i^1].f+=x;
            i=fa[e[i^1].v];
        }
        ans+=x*dis[T];
    }
    bool check(){
        for(int i=head[S];i;i=e[i].pre)
            if(e[i].f) return false;
        return true;
    }
    int hao(int x,int y){return (x-1)*m+y;}
    int main(){
        int tot=0;
        while(scanf("%s",ch[n+1]+1)!=EOF) n++;
        m=strlen(ch[1]+1);SS=n*m+1;TT=SS+1;S=TT+1;T=S+1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                if(ch[i][j]=='#') continue;
                if(i+j&1){
                    if(i==1||j==1||i==n||j==m) add(hao(i,j),TT,1,1);
                    d[SS]-=2;d[hao(i,j)]+=2;
                    for(int k=0;k<4;k++){
                        int x=i+dx[k],y=j+dy[k];
                        if(x<1||x>n||y<1||y>m||ch[x][y]=='#') continue;
                        add(hao(i,j),hao(x,y),1,0);
                    }
                }
                else {
                    if(i==1||j==1||i==n||j==m) add(SS,hao(i,j),1,1);
                    d[TT]+=2;d[hao(i,j)]-=2;
                }
            }
        for(int i=1;i<=TT;i++)
            if(d[i]>0) add(S,i,d[i],0);
            else if(d[i]<0) add(i,T,-d[i],0);
        add(TT,SS,inf,0);
        while(spfa()) updata();
        if(!check()) printf("-1");
        else printf("%d",ans/2);
        return 0;
    }
  • 相关阅读:
    springMVC(5)---导入excel文件数据到数据库
    springMVC(4)---生成excel文件并导出
    springMVC(3)---利用pdf模板下载
    springMVC(1)---@RequestMapping详解
    springMVC(2)---获取前段数据
    【JS】---5 JS通过事件隐藏显示元素
    【JS】---4用JS获取地址栏参数方法
    【功能代码】---3 JS判断字符串是否包含某个字符串
    基于maven的ssm框架整合
    java提高(9)---HashMap解析
  • 原文地址:https://www.cnblogs.com/harden/p/6629192.html
Copyright © 2011-2022 走看看