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 (费用流 拆点)的更多相关文章

  1. hoj 2543 (费用流 拆边)

    http://acm.hit.edu.cn/hoj/problem/view?id=2543 1.将原图中的每条边(u, v)拆成两条:(u, v, Ci, 0), (u, v, ∞, Ei) 2.购 ...

  2. hdu 1853 (费用流 拆点)

    // 给定一个有向图,必须用若干个环来覆盖整个图,要求这些覆盖的环的权值最小. 思路:原图每个点 u 拆为 u 和 u' ,从源点引容量为 1 费用为 0 的边到 u ,从 u' 引相同性质的边到汇点 ...

  3. UVa 2197 & 拆点分环费用流

    题意: 给你一个带权有向图,选择一些边组成许多没有公共边的环,使每个点都在k个环上,要求代价最小. SOL: 现在已经养成了这种习惯,偏题怪题都往网络流上想... 怎么做这题呢... 对我们看到每个点 ...

  4. CF 277E Binary Tree on Plane (拆点 + 费用流) (KM也可做)

    题目大意: 平面上有n个点,两两不同.现在给出二叉树的定义,要求树边一定是从上指向下,即从y坐标大的点指向小的点,并且每个结点至多有两个儿子.现在让你求给出的这些点是否能构成一棵二叉树,如果能,使二叉 ...

  5. HDU 4780 Candy Factory(拆点费用流)

    Problem Description   A new candy factory opens in pku-town. The factory import M machines to produc ...

  6. BZOJ 1877 晨跑 拆点费用流

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1877 题目大意: Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧 ...

  7. hdu 1853(拆点判环+费用流)

    Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others)Total ...

  8. 洛谷 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 ...

  9. Codeforces 730I [费用流]

    /* 不要低头,不要放弃,不要气馁,不要慌张 题意: 给两行n个数,要求从第一行选取a个数,第二行选取b个数使得这些数加起来和最大. 限制条件是第一行选取了某个数的条件下,第二行不能选取对应位置的数. ...

随机推荐

  1. Bitnami 2015

    WordPress WordPress is one of the world's most popular web publishing platforms for building blogs a ...

  2. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-如何动态显示当前运行行

    在F11运行状态下,点击Online-Display Flow Control然后可以看到绿色的行就是当前正在运行行     更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http:// ...

  3. 在FASTBuild中使用Caching

    上一篇:初识FASTBuild 在FASTBuild中使用缓存只需要注意三个环节: 一.设置编译选项 对于GCC\SNC\Clang编译器,没有特殊的要求 对于MSVC编译器,必须设置/Z7调试模式. ...

  4. python——深刻理解Python中的元类(metaclass)

    译注:这是一篇在Stack overflow上 很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉 ...

  5. 【Python】八大排序算法的比较

    排序是数据处理比较核心的操作,八大排序算法分别是:直接插入排序.希尔排序.简单选择排序.堆排序.冒泡排序.快速排序.归并排序.基数排序 以下是排序图解: 直接插入排序 思想 直接插入排序是一种最简单的 ...

  6. 如何查看mysql数据库的引擎/MySQL数据库引擎详解

    一般情况下,mysql会默认提供多种存储引擎,你可以通过下面的查看: 看你的mysql现在已提供什么存储引擎:mysql> show engines; 看你的mysql当前默认的存储引擎:mys ...

  7. ios 第三方qq登陆,号码禁止授权

    在以下加入測试账号就可以 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWxpbmNleGlhb2hhbw==/font/5a6L5L2T/fontsiz ...

  8. Android BlueDroid(三):BlueDroid蓝牙开启过程enable

    关键词:bluedroid  enableNative BTIF_TASK  BTU_TASK bt_hc_work_thread set_power  preload GKI作者:xubin3417 ...

  9. ace admin 下拉选择Multiple-select组件

    一.组件说明以及API 1.第一个组件是写bootstrap table的主人公 wenzhixin 封装的一个组件—— multiple-select.这个组件风格简单.文档全.功能强大.但是觉得它 ...

  10. vue 父子组件属性传递

    父子组件属性传递 注意:0.谁被引用,谁就算子组件  1.属性命名最好完全小写,否则需要如下格式转换:myAttr == my-attr 2.引入的vue组件后必须通过 components 注册才能 ...