一、题目

点此看题

二、解法

我一开始一直想不出来,直接刚这个题实在是太复杂了,因为一开始就是不合法的。

下次遇到复杂的题一定要想 调整法 ,我再不往这个方向想我吔屎

好了言归正传,我们先找一组可行的解,但不是最优的,我们想法设法地把他调整到最优。可行的解很容易找啊,把所有空格子改成 \(1\) ,所有线索改成格子的个数。但你可能要问如果有些格子不能调整怎么办呢?不要怕直接刚,如果我们最后能把这些格子调整回来那就没问题,而且这样做很方便。

如果从网络流方面来考虑的话那么把费用放在边上,然后我们用网络流来调整。请注意这个条件:输入保证这个从格式上来说一定是个合法的Kakuro 谜题,即每一段连续的空格的左边或者上面的格子包含线索。因为现在的图是合法的,所以可以把空格子当成边,连接两个线索,这样源汇的一条路径增加 \(1\) 的流量就表示这些格子的数都增加 \(1\) ,那么我们这样建图:

  • 源点连横着的线索,设原来的数字的 \(x\) ,现在的数字是 \(y\) ,改变权值的花费是 \(c\) ,如果 \(x>y\) ,说明改小了,如果需要的话我们可以回退这个操作,也就是连一条容量 \(x-y\) 费用为 \(-c\) 的边。然后还可以暴力调大,那么连一条容量为 \(inf\) 费用为 \(c\) 的边。
  • 竖着的线索连汇点,和上面的连法同理。
  • 设格子连接的两个线索是 \(i,j\) ,那么 \(i,j\) 先连一条容量为 \(x-y\) 的费用为 \(-c\)(此时 \(y=1\)),然后类似地连一条容量为 \(inf\) 费用为 \(c\) 的边。

大概的图就建好了,然后我们跑最小费用可行流就可以达到调整的目的了,也就是在 \(cost\geq 0\) 时退出。还有一个悬而未决的问题,就是不能调整的点怎么办,如果我们把 \(c\) 设置为 \(inf\) ,那么费用流肯定会使用对应的 \(-inf\) 的边,那么这个点就被调整回原来的状态了。

怎么判断无解呢?就是有些不能改的点没有被调整回原来的状态(\(-inf\) 的边没有满流),或者是不能改的点增加了数字(\(inf\) 的边有流量通过),那么都是不合法的。

但我怎么还是感觉有点不对劲呢?可能我还需要多想一想

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int M = 1005;
const int N = 35;
const int inf = 1e9;
#define int long long
int read()
{
int x=0,f=1;char c;
while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
int n,m,tot,cnt,f[M],a[N][N],id1[N][N],id2[N][N];
int ans,s,t,dis[M],lst[M],pre[M],in[M],flow[M];
int r[N][N],c[N][N],o[N][N],up[N][N],down[N][N];
struct edge
{
int v,f,c,next;
edge(int V=0,int F=0,int C=0,int N=0) : v(V) , f(F) , c(C) , next(N) {}
}e[M*M];
void add(int u,int v,int c,int fl)
{
e[++tot]=edge(v,fl,c,f[u]),f[u]=tot;
e[++tot]=edge(u,0,-c,f[v]),f[v]=tot;
}
int bfs()
{
queue<int> q;
for(int i=0;i<=t;i++) dis[i]=1e18;
dis[s]=0;pre[s]=-1;flow[s]=inf;
q.push(s);
while(!q.empty())
{
int u=q.front();q.pop();
in[u]=0;
for(int i=f[u];i;i=e[i].next)
{
int v=e[i].v,c=e[i].c;
if(dis[v]>dis[u]+c && e[i].f>0)
{
dis[v]=dis[u]+c;
pre[v]=u;lst[v]=i;
flow[v]=min(flow[u],e[i].f);
if(!in[v]) in[v]=1,q.push(v);
}
}
}
return dis[t]<0;
}
int Abs(int x)
{
return x>0?x:-x;
}
signed main()
{
n=read();m=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
a[i][j]=read();
if(a[i][j]==1 || a[i][j]==3) id1[i][j]=++cnt;
if(a[i][j]==2 || a[i][j]==3) id2[i][j]=++cnt;
}
s=0;t=cnt+1;tot=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(a[i][j]==1 || a[i][j]==3) r[i][j]=read();
if(a[i][j]==2 || a[i][j]==3) c[i][j]=read();
if(a[i][j]==4) o[i][j]=read();
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(a[i][j]==1 || a[i][j]==3)
{
int x=read(),k=i+1;
if(x==-1) x=inf;
while(k<=n && a[k][j]==4)
up[k++][j]=id1[i][j];
k=k-i-1;
ans+=Abs(k-r[i][j])*x;
if(r[i][j]>k) add(s,id1[i][j],-x,r[i][j]-k);
add(s,id1[i][j],x,inf);
}
if(a[i][j]==2 || a[i][j]==3)
{
int x=read(),k=j+1;
if(x==-1) x=inf;
while(k<=m && a[i][k]==4)
down[i][k++]=id2[i][j];
k=k-j-1;
ans+=Abs(k-c[i][j])*x;
if(c[i][j]>k) add(id2[i][j],t,-x,c[i][j]-k);
add(id2[i][j],t,x,inf);
}
if(a[i][j]==4)
{
int x=read();
if(x==-1) x=inf;
ans+=Abs(o[i][j]-1)*x;
if(o[i][j]>1) add(up[i][j],down[i][j],-x,o[i][j]-1);
add(up[i][j],down[i][j],x,inf);
}
}
while(bfs())
{
ans+=flow[t]*dis[t];
int zy=t;
while(zy!=s)
{
e[lst[zy]].f-=flow[t];
e[lst[zy]^1].f+=flow[t];
zy=pre[zy];
}
}
for(int i=2;i<=tot;i+=2)
{
if(e[i].c==inf && e[i^1].f>0)
{
puts("-1");
return 0;
}
if(e[i].c==-inf && e[i].f>0)
{
puts("-1");
return 0;
}
}
printf("%lld\n",ans);
}

[BJWC2018] Kakuro的更多相关文章

  1. HDU 3338 Kakuro Extension (网络流,最大流)

    HDU 3338 Kakuro Extension (网络流,最大流) Description If you solved problem like this, forget it.Because y ...

  2. hdu3338 Kakuro Extension 最大流

    If you solved problem like this, forget it.Because you need to use a completely different algorithm ...

  3. 「BJWC2018」Border 的四种求法

    「BJWC2018」Border 的四种求法 题目描述 给一个小写字母字符串 \(S\) ,\(q\) 次询问每次给出 \(l,r\) ,求 \(s[l..r]\) 的 Border . \(1 \l ...

  4. 洛谷 P4478 [BJWC2018]上学路线

    洛谷 P4478 [BJWC2018]上学路线 原题 神仙题orz,竟然没有1A....容斥+卢卡斯+crt?? 首先用容斥做,记\(f[i][0/1]\)表示到i号点经过了奇数/偶数个点的方案数,因 ...

  5. BZOJ1229 & 洛谷2917:[USACO2008 NOV]toy 玩具 & 洛谷4480:[BJWC2018]餐巾计划问题——题解

    标题很长emmm…… [USACO2008 NOV]toy 玩具 https://www.luogu.org/problemnew/show/P2917 https://www.lydsy.com/J ...

  6. HDU3338:Kakuro Extension(最大流)

    Kakuro Extension Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. HDU3338 Kakuro Extension —— 最大流、方格填数类似数独

    题目链接:https://vjudge.net/problem/HDU-3338 Kakuro Extension Time Limit: 2000/1000 MS (Java/Others)     ...

  8. 使用GAC加速 解决CSP问题 Kakuro - Cross Sums

    Kakuro - Cross Sums 问题如下 一个简单的例子 可以看出限制条件是某行或某列的某几个空白格子求和等于某个值,且每一个限制中的格子所填的数必须为1-9且互异. 直接暴力搜索,空白格子太 ...

  9. 洛谷 P4470 [BJWC2018]售票

    P4470 [BJWC2018]售票 C 市火车站最近出现了一种新式自动售票机.买票时,乘客要先在售票机上输入终点名称.一共有N 处:目的地,随着乘客按顺序输入终点名称的每个字母,候选终点站数目会逐渐 ...

随机推荐

  1. PAT L2-005. 集合相似度 【stl set】

    给定两个整数集合,它们的相似度定义为:Nc/Nt*100%.其中Nc是两个集合都有的不相等整数的个数,Nt是两个集合一共有的不相等整数的个数.你的任务就是计算任意一对给定集合的相似度. 输入格式: 输 ...

  2. P1337 [JSOI2004]平衡点(模拟退火)题解

    题意: 如图:有n个重物,每个重物系在一条足够长的绳子上.每条绳子自上而下穿过桌面上的洞,然后系在一起.图中X处就是公共的绳结.假设绳子是完全弹性的(不会造成能量损失),桌子足够高(因而重物不会垂到地 ...

  3. Linux 驱动框架---驱动中的并发

    并发指多个执行单元被同时.并行的执行,而并发执行的单元对共享资源的访问就容易导致竟态.并发产生的情况分为抢占和并行(多核)和硬抢占(中断).Linux为解决这一问题增加了一系列的接口来解决并发导致的竟 ...

  4. JavaScript & Atomics

    JavaScript & Atomics Atomics 对象提供了一组静态方法对 SharedArrayBuffer 和 ArrayBuffer 对象进行原子操作. Atomics.add ...

  5. how to input special keyboard symbol in macOS(⌘⇧⌃⌥)

    how to input special keyboard symbol in macOS(⌘⇧⌃⌥) emoji ctrl + command + space / ⌘⇧⌃ ⌘⇧⌃ Character ...

  6. nodejs 显示进度条插件

    ora 显示loading.. progress 进度条 progress var ProgressBar = require("progress"); var bar = new ...

  7. go-admin在线开发平台学习-3[细节解析]

    本章节主要的内容是对go-admin中的一些有趣编码进行分析,为自己以后提供一些借鉴 使用cli方式启动项目 使用cobra[眼镜蛇]完成强壮cli的工具,确保稳定. 使用cli的方式启动项目的好处显 ...

  8. 发布Jar包到maven中央仓库

    什么是maven中央仓库 maven是java世界最流行的构建工具,构建内容囊括了一个java项目的整个生命周期.其中最重要的功能就是依赖管理,maven通过一个类似云的ftp站点统一管理所有java ...

  9. CTS camera的基础操作和debug

    手机端 设置永久不锁屏 1 CTS 进入cts目录tools 运行以下命令 ./cts-tradefed adb devices找设备数串 整跑 run cts -m CtsCameraTestCas ...

  10. 看完就懂--CSS选择器优先级的计算

    CSS选择器优先级的计算 什么是选择器的优先级 优先级的计算与比较(一) - 优先级具有可加性 - 选择器优先级不会超过自身最大数量级 - 同等优先级情况下,后写的覆盖前写的 - 并集选择器之间的优先 ...