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. 【思维题 最大权闭合子图】loj#6045. 「雅礼集训 2017 Day8」价

    又是经典模型的好题目 题目描述 人类智慧之神 zhangzj 最近有点胖,所以要减肥,他买了 NN 种减肥药,发现每种减肥药使用了若干种药材,总共正好有 NN 种不同的药材. 经过他的人脑实验,他发现 ...

  2. Mysql关闭和修改密码

    数据库的关闭方法: 1.优雅的关闭数据库的方法:mysqladmin -uroot -p123456 shutdown 2.脚本关闭:/etc/init.d/mysqld stop 3.使用kill信 ...

  3. hprose 1.0(rpc 框架) - 内部数据标准

    hprose 1.0 内部数据标准 方法的描述  {    // 请求调用格式    'C'.writeString('method1').'a'.count($params).'{'.'m'.cou ...

  4. JZOJ 2499. 东风谷早苗

    2499. 东风谷早苗 (Standard IO) Time Limits: 1000 ms  Memory Limits: 131072 KB  Detailed Limits   Goto Pro ...

  5. django-simple-captcha 验证码干扰线随机点位

    CAPTCHA_NOISE_FUNCTIONS = ( 'captcha.helpers.noise_null',# 设置样式 'captcha.helpers.noise_arcs',# 设置干扰线 ...

  6. dijkstra与他的优化!!!

    目录 SPFA已死,有事烧纸 Dijkstra 配对堆 引言 讲解 合并 修改 弹出堆顶pop 代码 结合! 1 2 @ SPFA已死,有事烧纸 其实我本人也是一个SPFA的忠诚用户,至少我的最少费用 ...

  7. OpenCV学习笔记(十) 直方图操作

    直方图计算 直方图可以统计的不仅仅是颜色灰度, 它可以统计任何图像特征 (如 梯度, 方向等等).直方图的一些具体细节: dims: 需要统计的特征的数目, 在上例中, dims = 1 因为我们仅仅 ...

  8. Redis实现之字典跳跃表

    跳跃表 跳跃表是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的.跳跃表支持平均O(logN).最坏O(N)的时间复杂度查找,还可以通过顺序性操作来批量处理节 ...

  9. 关于spark入门报错 java.io.FileNotFoundException: File file:/home/dummy/spark_log/file1.txt does not exist

    不想看废话的可以直接拉到最底看总结 废话开始: master: master主机存在文件,却报 执行spark-shell语句:  ./spark-shell  --master spark://ma ...

  10. STL学习笔记5--map and multimap

    Maps是一种关联式容器,包含“关键字/值”对. Multimaps和maps很相似,但是MultiMaps允许重复的元素. 简单介绍: 1.声明,首先包含头文件 “map” map <int, ...