BZOJ 4213 贪吃蛇 上下界费用流 网络流
https://darkbzoj.cf/problem/4213
https://www.cnblogs.com/DaD3zZ-Beyonder/p/5733326.html 题目描述 dbzoj又崩了存个代码
一条对答案有贡献的蛇一定有两个点在边界上且这两个点都只连了一条边,这条蛇上的其他点一定都连了两条边。
把格子按照如国际象棋棋盘的样式黑白填充,那么一条蛇是一条链(或者环),链上的点黑白交错。
对每个白点匹配两个相邻的黑点(黑白填充是为了方便建图(类似于二分图匹配)),只能匹配一个相邻点的点的数量的最小值/2就是最少的有贡献的蛇的数量。
所以建图为
s -> 白 流量2 费用0 上下界2
黑 -> t 流量2 费用0 上下界2
白 -> 相邻黑 流量1费用0
边缘白 -> t 流量1费用1
s -> 边缘黑 流量1费用1
改造成上下界的就可以了。同这道题→BZOJ2055 80人环游世界
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
#define LL long long
const int maxn=;
int n=,m=,mx=,ss=,tt=,S=,T=,z;
char ch[][];
struct nod{
int y,v,co,nex;
}e[maxn];
int head[]={},tot=;
int d[]={},id[][]={},ans=;
void init(int x,int y,int v,int co){
e[++tot].y=y;e[tot].v=v;e[tot].co=co;e[tot].nex=head[x];head[x]=tot;
e[++tot].y=x;e[tot].v=;e[tot].co=-co;e[tot].nex=head[y];head[y]=tot;
}
int dis[];bool vis[]={};
queue<int>q;
bool SPFA(){
memset(dis,,sizeof(dis));
memset(vis,,sizeof(vis));
int tn=dis[];
q.push(S);dis[S]=;vis[S]=;
while(!q.empty()){
int x=q.front(),y;q.pop();vis[x]=;
for(int i=head[x];i;i=e[i].nex){
y=e[i].y;
if(e[i].v>&&dis[y]>dis[x]+e[i].co){
dis[y]=dis[x]+e[i].co;
if(!vis[y]){vis[y]=;q.push(y);}
}
}
}
return dis[T]!=tn;
}
int dfs(int x,int flo){
if(x==T){
ans+=dis[x]*flo;return flo;
}vis[x]=;
int liu=,tv,y;
for(int i=head[x];i;i=e[i].nex){
y=e[i].y;
if(vis[y]||dis[y]!=dis[x]+e[i].co||e[i].v<=)continue;
tv=dfs(y,min(flo-liu,e[i].v));
liu+=tv;e[i].v-=tv;e[i^].v+=tv;
if(liu==flo)break;
}
return liu;
}
bool Check(int x,int y){if(x>=&&x<=n&&y>=&&y<=m&&ch[x][y]!='#')return ;return ;}
void Buildedge(){
for(int i=;i<=n;++i) for(int j=;j<=m;++j) id[i][j]=(i-)*m+j;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(ch[i][j]=='#')continue;
if((i+j)&){
d[ss]-=;d[id[i][j]]+=;
if(Check(i-,j))init(id[i][j],id[i-][j],,);
if(Check(i,j-))init(id[i][j],id[i][j-],,);
if(Check(i+,j))init(id[i][j],id[i+][j],,);
if(Check(i,j+))init(id[i][j],id[i][j+],,);
}
else {d[tt]+=;d[id[i][j]]-=;}
}
}
for(int i=;i<=tt;i++){
if(d[i]>)init(S,i,d[i],);
if(d[i]<) init(i,T,-d[i],);
}
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(i==||j==||i==n||j==m){
if(ch[i][j]=='#')continue;
if((i+j)&)init(id[i][j],tt,,);
else init(ss,id[i][j],,);
}
}
}
init(tt,ss,mx,);
}
int main(){
//freopen("a.in","r",stdin);
n=;
while(~scanf("%s",ch[n]+))++n;
n--;
for(int i=;;++i){m=i-;if(ch[][i]!='.'&&ch[][i]!='#')break;}
mx=n*m;ss=mx+;tt=ss+;S=tt+;T=S+;
Buildedge();
while(SPFA()){memset(vis,,sizeof(vis));dfs(S,mx);}
int f=;
for(int i=head[S];i;i=e[i].nex)if(e[i].v)f=;
if(f)printf("%d\n",ans/);
else printf("-1\n");
return ;
}
BZOJ 4213 贪吃蛇 上下界费用流 网络流的更多相关文章
- BZOJ 4108: [Wf2015]Catering [上下界费用流]
4108: [Wf2015]Catering 题意:有一家装备出租公司收到了按照时间顺序排列的n个请求. 这家公司有k个搬运工.每个搬运工可以搬着一套装备按时间顺序去满足一些请求.一个搬运工从第i个请 ...
- 【有源汇上下界费用流】BZOJ 3876 [Ahoi2014]支线剧情
题目链接: http://www.lydsy.com:808/JudgeOnline/problem.php?id=3876 题目大意: 给定一张拓扑图(有向无环图),每条边有边权,每次只能从第一个点 ...
- BZOJ 3876: [Ahoi2014]支线剧情 [上下界费用流]
3876: [Ahoi2014]支线剧情 题意:每次只能从1开始,每条边至少经过一次,有边权,求最小花费 裸上下界费用流...每条边下界为1就行了 注意要加上下界*边权 #include <io ...
- BZOJ.1927.[SDOI2010]星际竞速(无源汇上下界费用流SPFA /最小路径覆盖)
题目链接 上下界费用流: /* 每个点i恰好(最少+最多)经过一次->拆点(最多)+限制流量下界(i,i',[1,1],0)(最少) 然后无源汇可行流 不需要源汇. 注: SS只会连i',求SS ...
- BZOJ 3876 支线剧情 | 有下界费用流
BZOJ 3876 支线剧情 | 有下界费用流 题意 这题题面搞得我看了半天没看懂--是这样的,原题中的"剧情"指的是边,"剧情点"指的才是点. 题面翻译过来大 ...
- BZOJ2324 ZJOI2011营救皮卡丘(floyd+上下界费用流)
虽然不一定每次都是由编号小的点向编号大的走,但一个人摧毁的顺序一定是从编号小的到编号大的.那么在摧毁据点x的过程中,其只能经过编号小于x的点.并且这样一定合法,因为可以控制其他人先去摧毁所经过的点.那 ...
- 【BZOJ2055】80人环游世界 有上下界费用流
[BZOJ2055]80人环游世界 Description 想必大家都看过成龙大哥的<80天环游世界>,里面的紧张刺激的打斗场面一定给你留下了深刻的印象.现在就有这么 一个 ...
- 【BZOJ3876】[Ahoi2014]支线剧情 有上下界费用流
[BZOJ3876][Ahoi2014]支线剧情 Description [故事背景] 宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩 ...
- 【bzoj2324】[ZJOI2011]营救皮卡丘 最短路-Floyd+有上下界费用流
原文地址:http://www.cnblogs.com/GXZlegend/p/6832504.html 题目描述 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘 ...
随机推荐
- python3学习笔记.4.turtle绘图
先放上参考 https://docs.python.org/3/library/turtle.html //********************************************** ...
- 快速修改Matlab默认启动路径(Windows/Mac)
如何修改Matlab启动路径/Windows or Mac 控制台内输入一下两行命令,之后重启MATLAB即可 newpath = '你所要设定的路径'; userpath(newpath) ...
- 2016.6.19——C++杂记
C++杂记 补充的小知识点: 1.while(n--)和while(--n)区别: while(n--)即使不满足也执行一次循环后跳出. while(--n)不满足直接跳出循环,不执行语句. 用cou ...
- Android Bander设计与实现 - 设计
Binder Android IPC Linux 内核 驱动 摘要 Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有管道,system V IPC,socket等IPC ...
- Linux压缩打包方法连载之三:bzip2, bzcat 命令
Linux压缩打包方法有多种,本文集中讲解了bzip2, bzcat 命令的使用.案例说明,例如# 与 gzip 同样的,都是在计算压缩比的参数,-9 最佳,-1 最快. AD: 我们遇见Linux压 ...
- 二、springboot配置
一.启动类 在包根目录下添加启动类,必须包含main方法,再添加Spring Boot启动方法: SpringApplication.run(SampleController.class, args) ...
- vue总结 06组件
组件基础 基本示例 这里有一个 Vue 组件的示例: // 定义一个名为 button-counter 的新组件Vue.component('button-counter', { data: func ...
- Python_oldboy_自动化运维之路(二)
本节内容: 1.pycharm工具的使用 2.进制运算 3.表达式if ...else语句 4.表达式for 循环 5.break and continue 6.表达式while 循环 1.pycha ...
- python logging 日志
logging与print 区别,为什么需要logging? 在写脚本的过程中,为了调试程序,我们往往会写很多print打印输出以便用于验证,验证正确后往往会注释掉,一旦验证的地方比较多,再一一注释比 ...
- matlab转python
最近在做把matlab代码转成python代码,没有用过matlab,python也只是局限于爬虫,所以.... matlab与python最大的不同是,matlab的下标是从1开始的,python和 ...