洛谷P4486 Kakuro
题意:你有一个棋盘,某些格子是限制条件,形如"从这里开始下面所有连续空格的和为a"或"从这里开始向右的所有连续空格之和为b"一个格子可以同时拥有两个限制条件。
每个数都必须是正整数。
现在你可以把某些格子加/减1,并花费相应的代价。可以操作无数次。求把棋盘变得合法的最小代价。
解:没想出来,看了题解......
一开始想了数字和条件构成二分图,又想了行列连边,但是始终建不出图来。
行列连边。
因为既可以加又可以减不好搞,我们可以先全部转换成满足条件的最小值,然后往上加。
从最小值到初始值的时候,边权为负。之后边权为正。
不可修改的地方边权为INF。
然后跑一个最小费用可行流就是答案。
如何判断无解?
考虑每条边,如果有的边费用为INF但是有流量,就不合法。
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring> typedef long long LL;
const LL N = , M = , INF = 0x3f3f3f3f, J = ; struct Edge {
LL nex, v, c, len;
}edge[N << ]; LL top = ; LL e[N], d[N], vis[N], pre[N], flow[N];
std::queue<LL> Q;
LL fr[J][J], val[J][J], v2[J][J], cst[J][J], c2[J][J], m; inline void add(LL x, LL y, LL z, LL w) {
top++;
edge[top].v = y;
edge[top].c = z;
edge[top].len = w;
edge[top].nex = e[x];
e[x] = top; top++;
edge[top].v = x;
edge[top].c = ;
edge[top].len = -w;
edge[top].nex = e[y];
e[y] = top;
return;
} inline bool SPFA(LL s, LL t) {
memset(d, 0x3f, sizeof(d));
d[s] = ;
flow[s] = INF;
vis[s] = ;
Q.push(s);
while(!Q.empty()) {
LL x = Q.front();
Q.pop();
vis[x] = ;
for(LL i = e[x]; i; i = edge[i].nex) {
LL y = edge[i].v;
if(edge[i].c && d[y] > d[x] + edge[i].len) {
d[y] = d[x] + edge[i].len;
pre[y] = i;
flow[y] = std::min(flow[x], edge[i].c);
if(!vis[y]) {
vis[y] = ;
Q.push(y);
}
}
}
}
return d[t] < INF;
} inline void update(LL s, LL t) {
LL temp = flow[t];
while(t != s) {
LL i = pre[t];
edge[i].c -= temp;
edge[i ^ ].c += temp;
t = edge[i ^ ].v;
}
return;
} inline LL solve(LL s, LL t, LL &cost) {
LL ans = ;
cost = ;
while(SPFA(s, t)) {
if(d[t] > ) {
break;
}
ans += flow[t];
cost += flow[t] * d[t];
update(s, t);
}
return ans;
} inline LL id(LL x, LL y) {
return (x - ) * m + y;
} int main() {
LL n, use = ;
scanf("%lld%lld", &n, &m);
for(LL i = ; i <= n; i++) {
for(LL j = ; j <= m; j++) {
scanf("%lld", &fr[i][j]);
}
}
for(LL i = ; i <= n; i++) {
for(LL j = ; j <= m; j++) {
if(fr[i][j] == ) {
continue;
}
else if(fr[i][j] == ) {
scanf("%lld", &val[i][j]);
}
else if(fr[i][j] == ) {
scanf("%lld", &v2[i][j]);
}
else if(fr[i][j] == ) {
scanf("%lld%lld", &val[i][j], &v2[i][j]);
}
else {
scanf("%lld", &val[i][j]);
}
}
}
for(LL i = ; i <= n; i++) {
for(LL j = ; j <= n; j++) {
if(fr[i][j] == ) {
continue;
}
else if(fr[i][j] == ) {
scanf("%lld", &cst[i][j]);
}
else if(fr[i][j] == ) {
scanf("%lld", &c2[i][j]);
}
else if(fr[i][j] == ) {
scanf("%lld%lld", &cst[i][j], &c2[i][j]);
}
else {
scanf("%lld", &cst[i][j]);
}
if(cst[i][j] == -) {
cst[i][j] = INF;
}
if(c2[i][j] == -) {
c2[i][j] = INF;
}
}
}
// read over
LL lm = n * m;
LL s = lm * + ;
LL t = s + ;
for(LL i = ; i <= n; i++) {
for(LL j = ; j <= m; j++) {
if(fr[i][j] == ) {
continue;
}
if(fr[i][j] == || fr[i][j] == ) {
// id(i, j)
LL cnt = ;
for(LL k = i + ; k <= n; k++) {
if(fr[k][j] == ) {
cnt++;
}
else {
break;
}
}
// val[i][j] - cnt
if(val[i][j] > cnt) {
add(s, id(i, j), val[i][j] - cnt, -cst[i][j]);
}
add(s, id(i, j), INF, cst[i][j]);
use += cst[i][j] * abs(val[i][j] - cnt);
}
if(fr[i][j] == || fr[i][j] == ) {
LL cnt = ;
for(LL k = j + ; k <= m; k++) {
if(fr[i][k] == ) {
cnt++;
}
else {
break;
}
}
if(v2[i][j] > cnt) {
add(id(i, j) + lm, t, v2[i][j] - cnt, -c2[i][j]);
}
add(id(i, j) + lm, t, INF, c2[i][j]);
use += c2[i][j] * abs(v2[i][j] - cnt);
}
if(fr[i][j] == ) {
LL a, b;
for(LL k = i - ; k >= ; k--) {
if(fr[k][j] == || fr[k][j] == ) {
a = id(k, j);
break;
}
}
for(LL k = j - ; k >= ; k--) {
if(fr[i][k] == || fr[i][k] == ) {
b = id(i, k) + lm;
break;
}
}
if(val[i][j] > ) {
add(a, b, val[i][j] - , -cst[i][j]);
}
add(a, b, INF, cst[i][j]);
use += cst[i][j] * abs(val[i][j] - );
}
}
} LL ans;
solve(s, t, ans);
ans += use; /*if(ans >= INF) {
puts("-1");
return 0;
}*/
for(int i = ; i <= top; i += ) {
if(abs(edge[i].len) == INF && (edge[i].c && edge[i ^ ].c)) {
puts("-1");
return ;
}
} printf("%lld", ans);
return ;
}
AC代码
思考:能否不转换为最小?好像无法判断是否合法...
洛谷P4486 Kakuro的更多相关文章
- Solution -「BJWC 2018」「洛谷 P4486」Kakuro
\(\mathcal{Description}\) Link. 有一个 \(n\times m\) 的网格图,其中某些格子被主对角线划成两个三角形,称这样的格子为特殊格:初始时,除了一些障碍格 ...
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
- 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.
没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...
- 洛谷P1108 低价购买[DP | LIS方案数]
题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...
- 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP
题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...
- 洛谷P1710 地铁涨价
P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交 讨论 题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...
- 洛谷P1371 NOI元丹
P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交 讨论 题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...
- 洛谷P1538迎春舞会之数字舞蹈
题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈 ...
- 洛谷八月月赛Round1凄惨记
个人背景: 上午9:30放学,然后因为学校举办读书工程跟同学去书城选书,中午回来开始打比赛,下午又回老家,中间抽出一点时间调代码,回家已经8:50了 也许是7月月赛时“连蒙带骗”AK的太幸运然而因同学 ...
随机推荐
- 一条insert语句插入数据库
CREATE TABLE test_main ( id INT NOT NULL, value VARCHAR(10), PRIMARY KEY(id) ); oracle插入方式:INSERT IN ...
- WPF编程,自定义鼠标形状的一种方法。
原文:WPF编程,自定义鼠标形状的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details/8727 ...
- mfc c++字符串类与 流输出
一.命名空间 所谓命名空间(namespace),是指标识符的各种可见范围.C++标准程序库中的所有标识符都被定义于一个名为std的命名空间(namespace)中.而我们要使用的string类也是一 ...
- C#精华面试题及答案 三
PS.学了两三年的软件开发到头来发现连一些基本的东西都没掌握,通过面试题来检验自己的水平,让学习变得更加有方向性,也为将来择业而打下基础,不至于到时候手忙脚乱. 一.选择,填空题 1. 在ADO.NE ...
- UWP简单示例(一):快速合成音乐MV
说明 本文发布时间较早,内容可能已过时.最新动态请关注 TypeScript 版本.(2019 年 3 月 注) 在线演示: 音频可视化(TypeScript) 准备 IDE:Visual Studi ...
- NAND Flash底层原理,SLC MLC TLC比较
NAND-Flash 的存储原理 固态硬盘最小单元的基本架构如下: 我们知道计算机中所有的信息储存最终都必须回归到 0与1,原则上,只要存储单元能提供两种或两种以上可供辨识的状态,便可以拿来纪录数据. ...
- Tkernel Package NCollection哈希基础的类
OpenCASCADE内用到了很多由诸如NCollection_Map, NCollection_DataMap, NCollection_DoubleMap, NCollection_Indexed ...
- 我用Python爬虫挣钱的那些事
在下写了10年Python,期间写了各种奇葩爬虫,挣各种奇葩的钱,写这篇文章总结下几种爬虫挣钱的方式. 1.最典型的就是找爬虫外包活儿. 这个真是体力活,最早是在国外各个freelancer网站上找适 ...
- Delphi中 弹出框的用法
Delphi中的提示框有 Application.MessageBox ShowMessage messagedlg 个人认为 相对来说 Application.MessageBox 更加灵活 也相 ...
- Selenium--调用js,对话框处理 (python)
前言: 本次教程针对Python语言,selenium教程(调用js,对话框处理) 一.对话框处理 更多的时候我们在实际的应用中碰到的并不是简单警告框,而是提供更多功能的会话框. 本节重点: 1.打开 ...