洛谷P4003 无限之环(费用流)
神仙题啊……不看题解我可能一年都不一定做得出来……FlashHu大佬太强啦
到底是得有怎样的脑回路才能一眼看去就是费用流啊……
建好图之后套个板子就好了,那么我们着重来讨论一下怎么建图
首先,对于每一个水管的支管,有且仅有一个其他支管与他相连,那么就不会漏水了。用网络流的说法,就是要每个支管容量只能为1且必须满流
然而因为最优情况图可能会被分成好几个连通块,于是我们得强制所有相邻的格子都有流量才行(就是确保连通块不管怎么划分都能流)
那么黑白染色冷静一下……黑点连源,白点连汇
然后费用是因为旋转产生的……然后因为和四周都有连边所以要拆点
把每一个点拆成上下左右中,中间为原点,四周代表四个方向的水管。中间点连上源或汇,四周的点分别向能到达的接触点连边,容1费0
然后讨论旋转产生的费用……坐稳了……
先是直线型
比如射线指向上面,那么就让左下右的点连上面,左右点连边容1费1(转一次就行),下面的点连边容1费2(要转两次)
然后直角的
转一次会变成这样
那么就可以看做是上面的点跑到下面来了,那么上下建一条容1费1的边就好,左右同理。如果转了两次,刚好可以从上右一起流,费2,所以不用新加边了
最后第三种
如果顺时针转一次相当于左边到了下面,于是连边容1费1,同理下右连边容1费1,上下连边容1费2(因为上下转换要转两次)
然后其他都和以上一样分类讨论就行了
上代码吧,写的zkw费用流
//minamoto
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
#define UP(x) x+turn*sum
#define RI(x) x+((turn+1)&3)*sum
#define DO(x) x+((turn+2)&3)*sum
#define LE(x) x+((turn+3)&3)*sum
#define MD(x) x+(sum<<2)//上面几个用来计算对应点的数组下标,上下左右中。。。
const int N=,M=;
int sum,S=,T;
int head[N],Next[M],ver[M],edge[M],cost[M],tot=;
int dis[N],vis[N],cur[N],ans;
int n,m,k=,totf,turn;
inline void add(int u,int v,int e,int c,int tp){
//tp表示点的颜色,如果是白点所有边都要反向,为了让流流向汇点
if(tp) u^=v^=u^=v;
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e,cost[tot]=c;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=,cost[tot]=-c;
}
queue<int> q;
bool spfa(){
memset(dis,-,sizeof(dis));
memset(vis,,sizeof(vis));
memcpy(cur,head,sizeof(int)*(T-S+));
q.push(T),dis[T]=,vis[T]=;
while(!q.empty()){
int u=q.front();q.pop(),vis[u]=;
for(int i=head[u];i;i=Next[i])
if(edge[i^]){
int v=ver[i],c=cost[i];
if(dis[v]<||dis[v]>dis[u]-c){
dis[v]=dis[u]-c;
if(!vis[v]) vis[v]=,q.push(v);
}
}
}
return ~dis[S];
}
int dfs(int u,int limit){
if(u==T||!limit) return limit;
int flow=,f;vis[u]=;
for(int &i=cur[u];i;i=Next[i]){
int v=ver[i];
if(dis[v]==dis[u]-cost[i]&&!vis[v]&&(f=dfs(v,min(limit,edge[i])))){
flow+=f,limit-=f;
edge[i]-=f,edge[i^]+=f;
ans+=f*cost[i];
if(!limit) break;
}
}
vis[u]=;
return flow;
}
int zkw(){
//zkw费用流板子
int flow=;
while(spfa()) flow+=dfs(S,inf);
return flow;
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read();
sum=n*m,T=sum*+;
for(int i=;i<n;++i)
for(int j=;j<m;++j,++k){
turn=;
int t=(i+j)&;
t?add(S,MD(k),inf,,):add(MD(k),T,inf,,);
if(i) add(DO(k-m),UP(k),,,t);
if(j) add(RI(k-),LE(k),,,t);
int op=read();
if(op&) add(UP(k),MD(k),,,t),++totf;
if(op&) add(RI(k),MD(k),,,t),++totf;
if(op&) add(DO(k),MD(k),,,t),++totf;
if(op&) add(LE(k),MD(k),,,t),++totf;
//统计一下总流量顺便和中间点连边
//因为每条边被记了两次,到时候要除以2
switch(op){
//直接把所有相同类型的一起处理掉
case :++turn;
case :++turn;
case :++turn;
case :
add(RI(k),UP(k),,,t);
add(DO(k),UP(k),,,t);
add(LE(k),UP(k),,,t);
break;
case :++turn;
case :++turn;
case :++turn;
case :
add(DO(k),UP(k),,,t);
add(LE(k),RI(k),,,t);
break;
case :++turn;
case :++turn;
case :++turn;
case :
add(DO(k),LE(k),,,t);
add(DO(k),UP(k),,,t);
add(DO(k),RI(k),,,t);
break;
}
}
printf("%d\n",(zkw()<<)==totf?ans:-);
return ;
}
洛谷P4003 无限之环(费用流)的更多相关文章
- 洛谷P4003 无限之环(infinityloop)(网络流,费用流)
洛谷题目传送门 题目 题目描述 曾经有一款流行的游戏,叫做 Infinity Loop,先来简单的介绍一下这个游戏: 游戏在一个 n ∗ m 的网格状棋盘上进行,其中有些小方格中会有水管,水管可能在格 ...
- BZOJ.5120.[清华集训2017]无限之环(费用流zkw 黑白染色)
题目链接 LOJ 洛谷 容易想到最小费用最大流分配度数. 因为水管形态固定,每个点还是要拆成4个点,分别当前格子表示向上右下左方向. 然后能比较容易地得到每种状态向其它状态转移的费用(比如原向上的可以 ...
- BZOJ5120 [2017国家集训队测试]无限之环 费用流
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ5120 题意概括 原题挺简略的. 题解 本题好难. 听了任轩笛大佬<国家队神犇>的讲课才 ...
- 洛谷.4015.运输问题(SPFA费用流)
题目链接 嗯..水题 洛谷这网络流二十四题的难度评价真神奇.. #include <queue> #include <cstdio> #include <cctype&g ...
- 洛谷P4015 运输问题(费用流)
传送门 源点向仓库连费用$0$,流量为储量的边,商店向汇点连费用$0$,流量为需求的边,然后仓库向商店连流量$inf$,费用对应的边,跑个费用流即可 //minamoto #include<io ...
- 洛谷P4014 分配问题(费用流)
传送门 可以把原图看做一个二分图,人在左边,任务在右边,求一个带权的最大和最小完美匹配 然而我并不会二分图做法,所以只好直接用费用流套进去,求一个最小费用最大流和最大费用最大流即可 //minamot ...
- 洛谷 - P4452 - 航班安排 - 费用流
https://www.luogu.org/problemnew/show/P4452 又一道看题解的费用流. 注意时间也影响节点,像题解那样建边就少很多了. #include<bits/std ...
- BZOJ 5120: [2017国家集训队测试]无限之环(费用流)
传送门 解题思路 神仙题.调了一个晚上+半个上午..这道咋看咋都不像图论的题竟然用费用流做,将行+列为奇数的点和偶数的点分开,也就是匹配问题,然后把一个点复制四份,分别代表这个点的上下左右接头,如果有 ...
- bzoj 5120 无限之环 & 洛谷 P4003 —— 费用流(多路增广SPFA)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5120 https://www.luogu.org/problemnew/show/P4003 ...
随机推荐
- python调试利器:最直观简洁的错误日志
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2018-08-30 17:12:27 # @Author : Sheldon (thi ...
- git format-patch的使用【转】
本文转载自:http://blog.chinaunix.net/uid-28621021-id-3487102.html git format-patch的使用 1.在dev1分支上,打出所有de ...
- consider increasing the maximum size of the cache.
虚拟机上搭建jenkins,出现unable to free [10] percent of the cache for Context [/jenkins] 提示让我加大缓存 consider in ...
- html5--1.9 img元素嵌入图片
html5--1.9 img元素嵌入图片 学习要点: img元素嵌入图片学习一个新属性:title 1.img的属性 1.src:必要属性,制定图片来源的路径; 2.alt属性:当图片无法显示时的替代 ...
- lxml解析html与元素定位
lxml.beautifulsoup和正则表达式都可以解析定位html元素.前两者中,lxml比beautifulsoup效率高,所以采用lxml解析html. 方法: from lxml impor ...
- hdu-2169 Computer(树形dp+树的直径)
题目链接: Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 1026 Table Tennis (30)(30 分)
A table tennis club has N tables available to the public. The tables are numbered from 1 to N. For a ...
- MySQL条件判断处理函数_20160925
MySQL条件判断处理 一.假如我想把salesperson 分成 5组,计算每个销售分组的业绩 首先先将销售分组 SELECT *, CASE WHEN salesperson IN (" ...
- wpf datagrid row的命中测试
1. 添加鼠标左键处理 AddHandler(DataGrid.MouseLeftButtonDownEvent, new RoutedEventHandler(grdStudyList_MouseL ...
- .NETFramework:WebClient
ylbtech-.NETFramework:WebClient 1.程序集 System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5 ...