hoj 2715 (费用流 拆点)
http://acm.hit.edu.cn/hoj/problem/view?id=2715
将每个格子 i 拆成两个点 i’, i’’并加边(i’, i’’, 1, -Vi), (i’, i’’, ∞, 0), (s, i’, ∞, 0); 控制只有一次能取到宝物。
对相邻的四个格子 j, Hi > Hj 则加边(i’’, j’, ∞, 0);
若格子 i 在边界上则加边(i’’, t, ∞, 0)。
限制增广次数小于等于 K 求最小费用流即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath> using namespace std; const int maxn = ;
const int maxm = ;
const int inf = 0x3f3f3f3f; struct MCMF
{
struct Edge
{
int v, c, w, next;
}p[maxm << ];
int e, head[maxn], dis[maxn], pre[maxn], cnt[maxn], sumFlow, n;
bool vis[maxn];
void init(int nt)
{
e = ; n = nt;
memset(head, -, sizeof(head[]) * (n + ) );
}
void addEdge(int u, int v, int c, int w)
{
p[e].v = v; p[e].c = c; p[e].w = w; p[e].next = head[u]; head[u] = e++;
swap(u, v);
p[e].v = v; p[e].c = ; p[e].w = -w; p[e].next = head[u]; head[u] = e++;
}
bool spfa(int S, int T)
{
queue <int> q;
for (int i = ; i <= n; ++i)
vis[i] = cnt[i] = , pre[i] = -, dis[i] = inf;
vis[S] = , dis[S] = ;
q.push(S);
while (!q.empty())
{
int u = q.front(); q.pop();
vis[u] = ;
for (int i = head[u]; i + ; i = p[i].next)
{
int v = p[i].v;
if (p[i].c && dis[v] > dis[u] + p[i].w)
{
dis[v] = dis[u] + p[i].w;
pre[v] = i;
if (!vis[v])
{
q.push(v);
vis[v] = ;
if (++cnt[v] > n) return ;
}
}
}
}
return dis[T] != inf;
}
int mcmf(int S, int T, int kt)
{
sumFlow = ;
int minFlow = , minCost = ;
while (spfa(S, T) && (kt--))
{
minFlow = inf + ;
for (int i = pre[T]; i + ; i = pre[ p[i ^ ].v ])
minFlow = min(minFlow, p[i].c);
sumFlow += minFlow;
for (int i = pre[T]; i + ; i = pre[ p[i ^ ].v ])
{
p[i].c -= minFlow;
p[i ^ ].c += minFlow;
}
minCost += dis[T] * minFlow;
}
return minCost;
}
void build(int nt, int kt)
{
int nnt = nt * nt;
init(nnt * + );
int val[][], height[][];
memset(val, 0x3f, sizeof(val));
memset(height, 0x3f, sizeof(height));
for (int i = ; i <= nt; ++i)
for (int j = ; j <= nt; ++j)
scanf("%d", &val[i][j]);
for (int i = ; i <= nt; ++i)
for (int j = ; j <= nt; ++j)
scanf("%d", &height[i][j]);
for (int i = ; i <= nt; ++i)
for (int j = ; j <= nt; ++j)
{
int pos = nt * (i - ) + j;
addEdge(, pos, inf, );
addEdge(pos, pos + nnt, ,-val[i][j]);
addEdge(pos, pos + nnt, inf,);
if (i == || i == nt || j == || j == nt)
addEdge(pos + nnt, n, inf, );
if (height[i][j] > height[i][j - ])
addEdge(pos + nnt, pos - , inf, );
if (height[i][j] > height[i][j + ])
addEdge(pos + nnt, pos + , inf, );
if (height[i][j] > height[i - ][j])
addEdge(pos + nnt, pos - nt, inf, );
if (height[i][j] > height[i + ][j])
addEdge(pos + nnt, pos + nt, inf, );
}
}
void solve(int nt, int kt)
{
build(nt, kt);
printf("%d\n", - mcmf(, n, kt));
}
}my;
int main()
{
int tcase, n, k;
scanf("%d", &tcase);
while (tcase--)
{
scanf("%d%d", &n, &k);
my.solve(n, k);
}
return ;
}
hoj 2715 (费用流 拆点)的更多相关文章
- hoj 2543 (费用流 拆边)
http://acm.hit.edu.cn/hoj/problem/view?id=2543 1.将原图中的每条边(u, v)拆成两条:(u, v, Ci, 0), (u, v, ∞, Ei) 2.购 ...
- hdu 1853 (费用流 拆点)
// 给定一个有向图,必须用若干个环来覆盖整个图,要求这些覆盖的环的权值最小. 思路:原图每个点 u 拆为 u 和 u' ,从源点引容量为 1 费用为 0 的边到 u ,从 u' 引相同性质的边到汇点 ...
- UVa 2197 & 拆点分环费用流
题意: 给你一个带权有向图,选择一些边组成许多没有公共边的环,使每个点都在k个环上,要求代价最小. SOL: 现在已经养成了这种习惯,偏题怪题都往网络流上想... 怎么做这题呢... 对我们看到每个点 ...
- CF 277E Binary Tree on Plane (拆点 + 费用流) (KM也可做)
题目大意: 平面上有n个点,两两不同.现在给出二叉树的定义,要求树边一定是从上指向下,即从y坐标大的点指向小的点,并且每个结点至多有两个儿子.现在让你求给出的这些点是否能构成一棵二叉树,如果能,使二叉 ...
- HDU 4780 Candy Factory(拆点费用流)
Problem Description A new candy factory opens in pku-town. The factory import M machines to produc ...
- BZOJ 1877 晨跑 拆点费用流
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1877 题目大意: Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧 ...
- hdu 1853(拆点判环+费用流)
Cyclic Tour Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/65535 K (Java/Others)Total ...
- 洛谷 1004 dp或最大费用流
思路: dp方法: 设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值. 则转移方程为 dp[i][j][k][l]=max(dp[i-1][j][k-1][l ...
- Codeforces 730I [费用流]
/* 不要低头,不要放弃,不要气馁,不要慌张 题意: 给两行n个数,要求从第一行选取a个数,第二行选取b个数使得这些数加起来和最大. 限制条件是第一行选取了某个数的条件下,第二行不能选取对应位置的数. ...
随机推荐
- Java Volatile keyword
Volatile修饰的成员变量在每次被线程訪问时,都强迫从主内存中重读该成员变量的值.并且,当成员变量发生变化时,强迫线程将变化值回写到主内存.这样在不论什么时刻,两个不同的线程总是看到某个成员变量的 ...
- 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-人机界面快速入门 TC3
右击添加一个PLC项,注意不要用中文 右击VISUs,添加一个视图对象 在POUs中打开MAIN,然后添加代码(定义了一个BOOL和一个INT类型变量) 工具箱中得到一个textfield ...
- lombok使用总结
前提 这篇文章主要介绍lombok的使用,至于lombok的源码和原理暂不探究,可以看上一篇文章插件化注解处理API去了解lombok的基本原理.参考资料: lombok官网 lombok官方教程-l ...
- android:numColumns="auto_fit" 失效问题
GridView 设置此属性无效:android:numColumns="auto_fit" ,请确认已经设置过 android:columnWidth="*dp&quo ...
- php中在局部作用域内访问全局变量
php中,由于作用域的限制,导致变量的访问限制: 1.局部作用域内不能访问全局变量 2.全局作用域内不能访问局部变量 对于第一种情况,如下代码将不能正常运行: <?php //局部作用域(函数内 ...
- 数组传到后台 string[] 获取
调试的 时候js 断点到后台 js上面也可以查看 传到后台的数据 方便查看~~
- android动画具体解释二 属性动画原理
property动画是一个强大的框架,它差点儿能使你动画不论什么东西. 你能够定义一个动画来改变对象的不论什么属性,不论其是否被绘制于屏幕之上. 一个属性动画在一定时间内多次改变一个属性(对象的一个字 ...
- putty英文乱码---DM8168_ETV_V1.1(路视明)
配置參照http://jingyan.baidu.com/article/c74d600048ed620f6a595d12.html 注意事项: 假设出现 英文也乱码.那么就是波特率设置的问题,应该这 ...
- Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL
Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL 1.1. $ 美元字符, php 黑头1 1.2. 默认变量的范围和声明:1 1.3 ...
- Atitit。sql2016标准化的规划方案 v3 q2a
Atitit.sql2016标准化的规划方案 v3 q2a 1. Sql标准化的历史3 1.1. Sql92标准4 1.2. Sql99标准4 1.3. SQL:2003为例,它包括以下9个部分 5 ...