Asa's Chess Problem
一、题目
给定一张 \(n\times n\) 的矩阵,每个点上面有黑棋或者是白棋,给定 \(\frac{n\times n}{2}\) 对可以交换的位置,每对位置一定在同一行 \(/\) 同一列。\(R[i],C[j]\) 分别表示 \(i\) 行 \(j\) 列的黑棋数,要求交换后 \(Rl[i]\leq R[i]\leq Rr[i],Cl[i]\leq C[i]\leq Cr[i]\)
问最小交换次数,如果无解输出 \(-1\)
二、解法
还是比较有意思的,因为这道题的限制在行列上,所以我们把行列拿出来建图。
最好把交换的过程在网络上表示出来,流量代表黑棋,一开始的初始状态有的黑棋就先 把流量给对应的行和列 。然后考虑表示这个限制,连一条上下界为限制的边到汇点 ,问题转化成带上下界的网络流。
最后来表示交换过程,同色的棋子可以忽略。一定要注意每对位置一定是同行或者同列,如果同行,那么把有黑棋的列连向无黑棋的列,如果同列,那么把有黑棋的行连向无黑棋的行。题目的这个条件保证了行和列是相对独立的,所以在我们的建图中并没有行和列的边(这也是一个思维定式,要敢于跳出来)
最后总结一下我们的建图,拿着这个图去跑最小费用可行流就可以了(无特殊说明费用为 \(0\)):
- \(s\) 连行,上下界都是初始黑棋数,行连 \(t\) ,上下界是题目中的要求。
- \(s\) 连列,上下界都是初始黑棋数,列连 \(t\) ,上下界是题目中的要求。
- \((x_1,y_1),(x_2,y_2)\) ,设 \((x_1,y_1)\) 初始有黑棋且不同色,如果 \(x_1=x_2\) ,\(y_1\) 连 \(y_2\) 一条容量为 \(1\) ,费用为 \(1\) 的边,如果 \(y_1=y_2\) ,\(x_1\) 连 \(x_2\) 一条容量为 \(1\) ,费用为 \(1\) 的边。
由于评测机挂了,我的代码只保证能通过样例,但方法是对的,请相信我。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
const int M = 205;
const int inf = 0x3f3f3f3f;
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,s,t,s1,t1,tot,sum,cost,f[M],in[M],out[M],a[55][55];
int ins[M],dis[M],flow[M],lst[M],pre[M],r[M],c[M];
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 xez(int u,int v,int a,int b,int c)
{
in[v]+=a;out[u]+=a;
add(u,v,c,b-a);
}
int bfs()
{
queue<int> q;
for(int i=0;i<=t;i++) dis[i]=inf;
flow[s]=inf;dis[s]=0;pre[s]=-1;
q.push(s);
while(!q.empty())
{
int u=q.front();q.pop();
ins[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;
flow[v]=min(flow[u],e[i].f);
pre[v]=u;lst[v]=i;
if(!ins[v])
{
ins[v]=1;
q.push(v);
}
}
}
}
return dis[t]<inf;
}
void solve()
{
s1=0;t1=2*n+1;s=2*n+2;t=2*n+3;
sum=cost=0;tot=1;
for(int i=0;i<=t;i++) f[i]=in[i]=out[i]=0;
for(int i=1;i<=n;i++) r[i]=c[i]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
a[i][j]=read();
r[i]+=a[i][j];
c[j]+=a[i][j];
}
for(int i=1;i<=n;i++)
{
int a=read(),b=read();
xez(s1,i,r[i],r[i],0);
xez(i,t1,a,b,0);
}
for(int i=1;i<=n;i++)
{
int a=read(),b=read();
xez(s1,i+n,c[i],c[i],0);
xez(i+n,t1,a,b,0);
}
for(int i=1;i<=n*n/2;i++)
{
int u=read(),v=read(),p=read(),q=read();
if(a[u][v]==a[p][q]) continue;
if(a[u][v]==0) swap(u,p),swap(v,q);
if(u==p) add(v+n,q+n,1,1);//同行
else add(u,p,1,1);//同列
}
for(int i=0;i<=t1;i++)
{
if(in[i]>out[i]) add(s,i,0,in[i]-out[i]),sum+=in[i]-out[i];
else add(i,t,0,out[i]-in[i]);
}
add(t1,s1,0,inf);
while(bfs())
{
sum-=flow[t];
cost+=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];
}
}
if(sum>0) puts("-1");
else printf("%d\n",cost);
}
int main()
{
while(~scanf("%d",&n)) solve();
}
Asa's Chess Problem的更多相关文章
- 【hihocoder 1424】 Asa's Chess Problem(有源汇上下界网络流)
UVALive-7670 ICPC北京2016-C题 hihocoder 1424 题意 有个 \(N\times N\) 的棋盘,告诉你每个格子黑色(1)或白色(0),以及每对能相互交换的同行或同列 ...
- [HihoCoder-1424] Asa's Chess Problem
有上下界的费用流 #include <stdio.h> #include <algorithm> #include <queue> #include <cst ...
- UVa 750 - 8 Queens Chess Problem
题目大意:八皇后问题,在一个8*8的棋盘上,放置8个皇后,使得任意两个皇后不在同一行上.不在同一列上.不在同一条对角线上,不过这道题预先给定了一个位置放置一个皇后,让你输出所有可能的答案. 经典的回溯 ...
- [2019HDU多校第二场][HDU 6591][A. Another Chess Problem]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6591 题目大意:二维坐标系上,所有满足\(5|2x+y\)的点都被设为障碍物,无法通过.现给出一对点, ...
- The 2016 ACMICPC Asia Beijing Regional Contest
A. Harmonic Matrix Counter (3/19) B. Binary Tree (1/14) C. Asa's Chess Problem (21/65) [ Problem ] 给 ...
- HDU 5742 Chess SG函数博弈
Chess Problem Description Alice and Bob are playing a special chess game on an n × 20 chessboard. ...
- 2016暑假多校联合---A Simple Chess
2016暑假多校联合---A Simple Chess Problem Description There is a n×m board, a chess want to go to the po ...
- dp - Codeforces Round #313 (Div. 1) C. Gerald and Giant Chess
Gerald and Giant Chess Problem's Link: http://codeforces.com/contest/559/problem/C Mean: 一个n*m的网格,让你 ...
- HDU 4405:Aeroplane chess(概率DP入门)
http://acm.split.hdu.edu.cn/showproblem.php?pid=4405 Aeroplane chess Problem Description Hzz loves ...
随机推荐
- Nginx基础 - 配置代理web服务
1.反向代理及负载均衡Nginx实现负载均衡用到了proxy_pass代理模块核心配置,将客户端请求代理转发至一组upstream虚拟服务池. 1)upstream配置语法 Syntax: upstr ...
- K8S(04)核心插件-coredns服务
K8S核心插件-coredns服务 目录 K8S核心插件-coredns服务 1 coredns用途 1.1 为什么需要服务发现 2 coredns的部署 2.1 获取coredns的docker镜像 ...
- Keepalived+LVS实现LNMP网站的高可用部署
Keepalived+LVS实现LNMP网站的高可用部署 项目需求 当我们访问某个网站的时候可以在浏览器中输入IP或者域名链接到Web Server进行访问,如果这个Web Server挂了, ...
- 使用Benchmark.NET测试代码性能
今天,我们将研究如何使用Benchmark.Net来测试代码性能.借助基准测试,我们可以创建基准来验证所做的更改是否按预期工作并且不会导致性能下降. 并非每个项目都需要进行基准测试,但是如果您正在开发 ...
- h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated
Reference 问题 ... h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype ...
- 蓝桥杯——试题 算法训练 Sereja and Squares
Java 代码 ```` import java.util.Scanner; public class Main { private static long num = 0; private stat ...
- auto switch HTTP protocol Chrome Extension
auto switch HTTP protocol Chrome Extension HTTPS auto switch to HTTP VPN https://chrome.google.com/w ...
- calendar merge date
calendar merge date componentDidMount () { const { monthDays, // monthDates, } = this.props; const d ...
- BGV再度爆发,流通市值破500万美金!
BGV似乎以超乎寻常的姿态,开启了爆发的模式.这两天,BGV一路上涨,日内最高涨至548.78美金,24小时成交额达到了98.07万美金,24小时成交量达到1844.93枚BGV,流通市值更是突破了5 ...
- 阿里面试这样问:redis 为什么把简单的字符串设计成 SDS?
2021开工第一天,就有小伙伴私信我,还给我分享了一道他面阿里的redis题(这家伙绝比已经拿到年终奖了),我看了以后觉得挺有意思,题目很简单,是那种典型的似懂非懂,常常容易被大家忽略的问题.这里整理 ...