【费用流】 ICPC 2016 China Final J. Mr.Panda and TubeMaster
表示“必须选”的模型
题目大意
题目分析
一个格子有四种方式看上去很难处理。将横竖两个方向分开考虑,会发现:因为收益只与相邻格子是否连通有关,所以可以将一个格子拆成表示横竖两个方向的,互相独立的点。

上图的格子里四个方向红边表示的就是一个格子的可能方向;拆点后所连蓝边的容量为1,费用即为连通两个格子的收益。
但是这样建图不能够表示某些格子必须要选。
考虑一个格子如果被选择了会发生什么:因为每个格子都处在环上,那么被选择的网格一定可以通过其他节点走到汇点。这意味着一个格子拆成的两个节点之间的边就可以先不建,而若最大流不等于网格总数,即有节点不可能被合法选中。
建图的时候一定要先理解清楚,因为有很多种错误方式,下图就是其中一个。

#include<queue>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
const int maxn = ;
const int maxm = ;
const int INF = 2e9; struct Edge
{
int u,v,f,c,cst;
Edge(int a=, int b=, int c=, int d=, int e=):u(a),v(b),f(c),c(d),cst(e) {}
}edges[maxm];
int sne,n,m,S,T;
bool ess[][],inq[maxn];
int tagl[][],tagr[][],valc[][],valr[][]; //tagl为入点,tagr为出点
int edgeTot,head[maxn],nxt[maxm],flw[maxn],cst[maxn],bck[maxn]; int read()
{
char ch = getchar();
int num = , fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = -;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
return num*fl;
}
void addedge(int u, int v, int c, int cst)
{
edges[edgeTot] = Edge(u, v, , c, cst), nxt[edgeTot] = head[u], head[u] = edgeTot++;
edges[edgeTot] = Edge(v, u, , , -cst), nxt[edgeTot] = head[v], head[v] = edgeTot++;
}
void maxFlow()
{
int mxFlw = , cost = ;
for (;;)
{
std::queue<int> q;
memset(flw, , sizeof flw);
memset(bck, , sizeof bck);
memset(cst, 0x3f3f3f3f, sizeof cst);
q.push(S), flw[S] = INF, cst[S] = ;
for (int tmp; q.size(); )
{
tmp = q.front(), q.pop(), inq[tmp] = ;
for (int i=head[tmp]; i!=-; i=nxt[i])
{
int v = edges[i].v;
if (cst[tmp]+edges[i].cst < cst[v]&&edges[i].f < edges[i].c){
bck[v] = i, cst[v] = cst[tmp]+edges[i].cst;
flw[v] = std::min(flw[tmp], edges[i].c-edges[i].f);
if (!inq[v]) inq[v] = , q.push(v);
}
}
}
if (!flw[T]) break;
for (int i=T; i!=S; i=edges[bck[i]].u)
edges[bck[i]].f += flw[T], edges[bck[i]^].f -= flw[T];
mxFlw += flw[T], cost += cst[T]*flw[T];
}
if (mxFlw!=n*m) puts("Impossible");
else printf("%d\n",-cost);
}
int main()
{
sne = read();
for (int cse=; cse<=sne; cse++)
{
printf("Case #%d: ",cse);
memset(ess, , sizeof ess);
memset(head, -, sizeof head);
edgeTot = , n = read(), m = read();
for (int i=; i<=n; i++)
for (int j=; j<m; j++)
valc[i][j] = read();
for (int i=; i<n; i++)
for (int j=; j<=m; j++)
valr[i][j] = read();
for (int i=, cnt=; i<=n; i++)
for (int j=; j<=m; j++)
tagl[i][j] = ++cnt, tagr[i][j] = ++cnt;
S = , T = tagr[n][m]+;
for (int i=; i<=n; i++)
for (int j=; j<=m; j++)
if ((i+j)&){ //为避免重复建边的处理技巧
if (j+ <= m) addedge(tagl[i][j], tagr[i][j+], , -valc[i][j]);
if (j- >= ) addedge(tagl[i][j], tagr[i][j-], , -valc[i][j-]);
}else{
if (i+ <= n) addedge(tagl[i][j], tagr[i+][j], , -valr[i][j]);
if (i+ >= ) addedge(tagl[i][j], tagr[i-][j], , -valr[i-][j]);
}
for (int i=read(); i; i--) ess[read()][read()] = ;
for (int i=; i<=n; i++)
for (int j=; j<=m; j++)
{
addedge(S, tagl[i][j], , );
addedge(tagr[i][j], T, , );
if (!ess[i][j]) addedge(tagl[i][j], tagr[i][j], , );
}
maxFlow();
}
return ;
}
END
【费用流】 ICPC 2016 China Final J. Mr.Panda and TubeMaster的更多相关文章
- ICPC 2016 China Final J. Mr.Panda and TubeMaster【最大费用最大流】
有一种限制下界强制选的,但是也可以不用 把每个格点拆成两个,一个连s一个连t,对于不是必选的连中间连流量1费用0边表示不选,然后黑白染色,黑点连横着白点连竖着,边权就是这条水管的权值,然后跑最大费用最 ...
- China Final J - Mr.Panda and TubeMaster
和一般的管道不同 不能类似“无限之环”或者“弯弯国”的建图,因为这两个题都是某些位置必须有,或者必须没有 但是本题可以有的位置随意,不能限制某个位置要么流2,要么流0,(实际上可能流了1过去) 所以建 ...
- J - Mr.Panda and TubeMaster
题解 我们可以把每个格子拆成两个点,一个表示横向的,一个表示纵向的,相邻的格子横向和纵向连边. 如果直接按照题意做的话,我们应当在横向和纵向的点之间连边,有限制的边设下界为1,然后跑可行流. 或者考虑 ...
- Gym101194J Mr.Panda and TubeMaster 二分图、费用流
传送门 看到这张图,是一个网格图,而且有回路限制,不难想到黑白染色. 一般来说我们对一张图黑白染色之后都是黑色点向白色点连边,但是这道题往这边想似乎就想不出建图方法了,因为"一个格子强制流满 ...
- 2016 ACM-ICPC China Finals #F Mr. Panda and Fantastic Beasts
题目链接$\newcommand{\LCP}{\mathrm{LCP}}\newcommand{\suf}{\mathrm{suf}}$ 题意 给定 $n$ 个字符串 $s_1, s_2, \dots ...
- 2016 China Final E - Bet
/************************************************************************* > File Name: E.cpp > ...
- 2016 China Final H - Great Cells
/************************************************************************* > File Name: H.cpp > ...
- 2016EC Final F.Mr. Panda and Fantastic Beasts
题目大意 \(T(1\leq T\leq42)\)组数据,给定\(n(2\leq n\leq 50000)\)个字符串\(S_{i}(n\leq\sum_{i=1}^{n}S_{i}\leq 2500 ...
- 2016 China Collegiate Programming Contest Final
2016 China Collegiate Programming Contest Final Table of Contents 2016 China Collegiate Programming ...
随机推荐
- ios 类似淘宝评论星星功能
创建星星视图: //星星 _myview = [[UIView alloc]initWithFrame:CGRectMake(95, 5, 200, 50)]; UIPanGestureRecogni ...
- Macbook 修复Office Excel 异常问题
manbook 版本的office excel 在一次崩溃后,每次打开excel 文件都会弹出以下烦人的错误告警,并且每次都会重新打开很多过去保存过的excel 文件. “在应用程序意外退出之前,Ex ...
- CCPC吉林站
A.The Fool #include <bits/stdc++.h> using namespace std; inline int read() { ,f=;char ch=getch ...
- 四则运算二(java web)
最近我和我的小伙伴yaoyali结成对子,共同写网页版的四则运算.虽然现在还没弄好,但是比起上次用纯java写的四则运算有了很大改进. 一.存放四则运算题目和答案的类 package com.jaov ...
- kali linux安装搜狗输入法
1. 更新软件源 vi /etc/apt/sources.list 2. 安装fcitx apt-get install fcitx 3. 下载deb包到指定目录, dpkg -i sogou**** ...
- postgresql修改数据库名
alter database abc rename to cba;
- Python网络编程中的服务器架构(负载均衡、单线程、多线程和同步、异步等)
这篇文章主要介绍服务器架构. 网络服务需要面对两个挑战. 第一个问题是核心挑战,要编写出能够正确处理请求并构造合适响应的代码. 第二个挑战是如何将网络代码部署到随系统自动启动的Windows服务或者是 ...
- SpringCloud服务的平滑上下线
http://blog.itpub.net/31545684/viewspace-2215300/ spring cloud eureka 参数配置 https://www.jianshu.com/p ...
- redis 大批量数据插入导致MISCONF Redis is configured to save RDB snapshots的解决
PS:之前写过一遍,那个方法没有彻底解决,现找到真正的解决方法 环境:redis 3.2.100 windows版(注意!!!这是关键),win10,redis客户端spring boot 2.0.7 ...
- MVC与Holla聊天工具
MVC 是一种设计模式, 它将应用划分为 3 个部分 : 数据( 模型). 展现层( 视图) 和用 户交互层( 控制器). 换句话说, 一个事件的发生是这样的过程 : 1. 用户和应用产生交互. 2. ...