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=,SS,TT,S,T,ans;
int dx[]={,,,-};
int dy[]={,-,,};
struct node{int v,f,w,pre;}e[N*];
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=;e[cnt].w=-w;e[cnt].pre=head[v];head[v]=cnt;
}
bool spfa(){
for(int i=;i<=T;i++) dis[i]=inf;
q.push(S);dis[S]=;
while(!q.empty()){
int u=q.front();q.pop();inq[u]=;
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]=;
}
}
}
return dis[T]!=inf;
}
void updata(){
int i=fa[T],x=inf;
while(i){
x=min(x,e[i].f);
i=fa[e[i^].v];
}
i=fa[T];
while(i){
e[i].f-=x;
e[i^].f+=x;
i=fa[e[i^].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-)*m+y;}
int main(){
int tot=;
while(scanf("%s",ch[n+]+)!=EOF) n++;
m=strlen(ch[]+);SS=n*m+;TT=SS+;S=TT+;T=S+;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++){
if(ch[i][j]=='#') continue;
if(i+j&){
if(i==||j==||i==n||j==m) add(hao(i,j),TT,,);
d[SS]-=;d[hao(i,j)]+=;
for(int k=;k<;k++){
int x=i+dx[k],y=j+dy[k];
if(x<||x>n||y<||y>m||ch[x][y]=='#') continue;
add(hao(i,j),hao(x,y),,);
}
}
else {
if(i==||j==||i==n||j==m) add(SS,hao(i,j),,);
d[TT]+=;d[hao(i,j)]-=;
}
}
for(int i=;i<=TT;i++)
if(d[i]>) add(S,i,d[i],);
else if(d[i]<) add(i,T,-d[i],);
add(TT,SS,inf,);
while(spfa()) updata();
if(!check()) printf("-1");
else printf("%d",ans/);
return ;
}

贪吃蛇(bzoj 4213)的更多相关文章

  1. 【BZOJ-4213】贪吃蛇 有上下界的费用流

    4213: 贪吃蛇 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 58  Solved: 24[Submit][Status][Discuss] Desc ...

  2. Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录

    一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...

  3. 用C++实现的贪吃蛇游戏

    我是一个C++初学者,控制台实现了一个贪吃蛇游戏. 代码如下: //"贪吃蛇游戏"V1.0 //李国良于2016年12月29日编写完成 #include <iostream& ...

  4. [LeetCode] Design Snake Game 设计贪吃蛇游戏

    Design a Snake game that is played on a device with screen size = width x height. Play the game onli ...

  5. JavaScript-简单的贪吃蛇小游戏

    实现逻辑: //获取Html中的格子(行,列) //建立数组存储所有格子(x,y) //建立数组用于存储蛇身(x,y) //生成随机坐标(x,y)的函数 //随机创建蛇身并存储到蛇身数组 //创建食物 ...

  6. juery实现贪吃蛇的游戏

    今天用juery做了一个贪吃蛇的游戏,代码比较简陋,不过作为这些天学习juery的成果,非常有成就感.另外关于代码内容如有雷同不胜荣幸. 更改了下 让头和身子的颜色不一样 这样好区分些,虽然还是不怎么 ...

  7. HTML 5 背离贪吃蛇 写成了类似于屏幕校准

    中间写了改 改了写 还是没做出自己满意的效果 ,看来自己的确不是一个走前端的料子.当然h5还是学一点好一点 具体说来 就是 在canvas 的画布中 鼠标点击后画上一个圆形 然后就有随机的在画布上面出 ...

  8. 控制台游戏引擎CGE——贪吃蛇

    今天我也来发一个控制台游戏.先看图: 缘起 LZ是一个有严重拖延症的人,表现的形式就是隔一段时间就要刷一刷博客园. 这不前几天,看到了魏大师<使用Lua脚本语言开发出高扩展性的系统...> ...

  9. 原生JS制作贪吃蛇小游戏

    感情都在代码里,来,干了!... <!doctype html> <html> <head> <meta http-equiv="Content-T ...

随机推荐

  1. java算法面试题:金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。

    package com.swift; public class RenMingBi { private static final char[] data = new char[]{'零','壹','贰 ...

  2. 基于 muse-ui 封装一个微信公众号上传插件 实现多图上传

    Vue.component('my-wx-upload', { template: ` <mu-grid-list :cols="3" :cellHeight="9 ...

  3. 【转】C++ 值传递、指针传递、引用传递详解

    而关于值传递,指针传递,引用传递这几个方面还会存在误区, 所有我觉的有必要在这里也说明一下~ 下文会通过例子详细说明哦 值传递: 形参是实参的拷贝,改变形参的值并不会影响外部实参的值.从被调用函数的角 ...

  4. 该网页无法正常运作 目前无法处理此请求HTTP ERROR 500?

    由于php.ini配置文件中错误显示关闭导致. 将下值由Off 变更为 On display_errors = On display_startup_errors = On

  5. thinkphp3.2.3如何只改变地址url中的某一个分隔符,其它保持不变

    今天教大家一个关于使用thinkphp3.2.3改变只改变地址url中的某一个分隔符的方法,首先大家来看看这个地址! 它的原始地址应该是/Home/Index/index/page/2.html,那我 ...

  6. VS2010官方下载地址

    http://download.microsoft.com/download/2/4/7/24733615-AA11-42E9-8883-E28CDCA88ED5/X16-42552VS2010Ult ...

  7. Darwin's Letter【达尔文的信】

    Darwin's Letter A letter written by Charles Darwin in 1875 has been returned to the Smithsonian Inst ...

  8. opencv中的仿射变换

    什么是仿射变换? 原理:1.一个任意的仿射变换都能表示为 乘以一个矩阵(线性变换) 接着再 加上一个向量(平移) 2.综上所述,我们能够用仿射变换来表示: 1)旋转(线性变换) 2)平移(向量加) 3 ...

  9. loj2073 「JSOI2016」扭动的回文串

    ref 主要是要理解"撑到"最长这个概念 (为啥我的代码这么长QAQ #include <iostream> #include <cstdio> using ...

  10. Selenium自动化测试框架的搭建 (转)

    http://www.51testing.com/html/96/86796-851606.html