题目大意:给出棋盘上的N个点的位置。如今问将这些点排成一行或者一列。或者对角线的最小移动步数(每一个点都仅仅能上下左右移动。一次移动一个)

解题思路:暴力+二分图最佳完美匹配

#include <cstdio>
#include <cstring> #define N 20
#define INF 0x3f3f3f3f
#define abs(x) ((x) > 0 ? (x) : (-(x)))
#define max(a,b)((a)>(b)? (a):(b))
#define min(a,b)((a)<(b)? (a):(b)) struct Node {
int x, y;
}node[N]; int w[N][N], left[N], Lx[N], Ly[N], slack[N];
int ans, n;
bool S[N], T[N]; bool match(int i) {
S[i] = true;
for (int j = 1; j <= n; j++) {
if (Lx[i] + Ly[j] == w[i][j] && !T[j]) {
T[j] = true;
if (!left[j] || match(left[j])) {
left[j] = i;
return true;
}
}
else slack[j] = min(slack[j], Lx[i] + Ly[j] - w[i][j]);
}
return false;
} void update() {
int a = 1 << 30;
for (int i = 1; i <= n; i++) if (S[i])
for (int j = 1; j <= n; j++) if (!T[j])
a = min(a, Lx[i] + Ly[i] - w[i][j]);
for (int i = 1; i <= n; i++) {
if (S[i]) Lx[i] -= a;
if (T[i]) Ly[i] += a;
}
} void KM() {
for (int i = 1; i <= n; i++) {
left[i] = Ly[i] = 0;
Lx[i] = -INF;
for (int j = 1; j <= n; j++)
Lx[i] = max(Lx[i], w[i][j]);
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++)
slack[j] = INF;
for (;;) {
for (int j = 1; j <= n; j++) S[j] = T[j] = 0;
if (match(i)) break;
int a = INF;
for (int j = 1; j <= n; j++)
if (!T[j])
a = min(a, slack[j]);
for (int j = 1; j <= n; j++) {
if (S[j]) Lx[j] -= a;
if (T[j]) Ly[j] += a;
}
}
}
int t = 0;
for (int i = 1; i <= n; i++)
t += Lx[i] + Ly[i];
ans = max(ans, t);
} void init() {
for (int i = 1; i <= n; i++)
scanf("%d%d", &node[i].x, &node[i].y);
} int cas = 1;
void solve() {
ans = -INF;
for (int j = 1; j <= n; j++) {
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
w[i][k] = abs(node[i].x - j) + abs(node[i].y - k);
w[i][k] = -w[i][k];
}
}
KM();
} for (int j = 1; j <= n; j++) {
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++) {
w[i][k] = abs(node[i].x - k) + abs(node[i].y - j);
w[i][k] = -w[i][k];
}
KM();
} for (int j = 1; j <= n; j++)
for (int i = 1; i <= n; i++) {
w[i][j] = abs(node[i].x - j) + abs(node[i].y - j);
w[i][j] = -w[i][j];
}
KM(); for (int j = 1; j <= n; j++)
for (int i = 1; i <= n; i++) {
w[i][j] = abs(node[i].x - j) + abs(node[i].y - (n - j + 1));
w[i][j] = -w[i][j];
}
KM();
printf("Board %d: %d moves required.\n\n", cas++, abs(ans));
} int main() {
while (scanf("%d", &n) != EOF && n) {
init();
solve();
}
return 0;
}

UVA - 1045 The Great Wall Game(二分图最佳完美匹配)的更多相关文章

  1. UVa 11383 少林决胜(二分图最佳完美匹配)

    https://vjudge.net/problem/UVA-11383 题意: 给定一个N×N矩阵,每个格子里都有一个正整数W(i,j).你的任务是给每行确定一个整数row(i),每列也确定一个整数 ...

  2. UVa1349 Optimal Bus Route Design(二分图最佳完美匹配)

    UVA - 1349 Optimal Bus Route Design Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...

  3. Ants(二分图最佳完美匹配)

    Ants Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6904   Accepted: 2164   Special Ju ...

  4. 【LA4043 训练指南】蚂蚁 【二分图最佳完美匹配,费用流】

    题意 给出n个白点和n个黑点的坐标,要求用n条不相交的线段把他们连接起来,其中每条线段恰好连接一个白点和一个黑点,每个点恰好连接一条线段. 分析 结点分黑白,很容易想到二分图.其中每个白点对应一个X结 ...

  5. Uva1349Optimal Bus Route Design(二分图最佳完美匹配)(最小值)

    题意: 给定n个点的有向图问,问能不能找到若干个环,让所有点都在环中,且让权值最小,KM算法求最佳完美匹配,只不过是最小值,所以把边权变成负值,输出时将ans取负即可 这道题是在VJ上交的 #incl ...

  6. UVa 1349 - Optimal Bus Route Design(二分图最佳完美匹配)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  7. ZOJ-3933 Team Formation (二分图最佳完美匹配)

    题目大意:n个人,分为两个阵营.现在要组成由若干支队伍,每支队伍由两个人组成并且这两个人必须来自不同的阵营.同时,每个人都有m个厌恶的对象,并且厌恶是相互的.相互厌恶的人不能组成一支队伍.问最多能组成 ...

  8. 【LA2238 训练指南】固定分区内存管理 【二分图最佳完美匹配,费用流】

    题意 早期的多程序操作系统常把所有的可用内存划分为一些大小固定的区域,不同的区域一般大小不同,而所有区域的大小之和为可用内存的大小.给定一些程序,操作系统需要给每个程序分配一个区域,使得他们可以同时执 ...

  9. HDU_2255 二分图最佳完美匹配 KM匈牙利算法

    一开始还没看懂这个算法,后来看了陶叔去年的PPT的实例演示才弄懂 用一个lx[]和ly[]来记录X和Y集合中点的权值,有个定理是 lx[i]+ly[j]==w[i][j](边权值) 则该点是最佳匹配, ...

随机推荐

  1. Oracle 的安装与使用

    一.文件下载 安装的是Oracle 11G,安装文件名为OracleXE112_Win32.zip, 官方文件下载地址:http://www.oracle.com/technetwork/databa ...

  2. Linux 之 LNMP服务器搭建-PHP

    LNMP服务器搭建-PHP 参考教程:[千峰教育] 安装: (1)解压源码包 cd /lnmp/srctar -jxvf php-7.3.2.tar.bz2cd php-7.3.2 (2)配置选项 . ...

  3. delphi 四舍五入Round函数【百帖整理】

    在最近版本的Delphi Pascal 编译器中,Round 函数是以 CPU 的 FPU (浮点部件) 处理器为基础的.这种处理器采用了所谓的 "银行家舍入法",即对中间值 (如 ...

  4. hdu 4503(数学,概率)

    湫湫系列故事——植树节 Time Limit: 1000/500 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  5. HDU 5972 Regular Number(字符串shift - and算法)

    题目链接  HDU5972 2016 ACM/ICPC 大连区域赛 B题 我们预处理出$b[i][j]$,$b[i][j] = 1$的意义是数字$i$可以放在第$j$位. 然后就开始这个匹配的过程. ...

  6. Codeforces 599E Sandy and Nuts(状压DP)

    题目链接 Sandy and Nuts 题意大概就是给出限制条件求出在该限制条件下树的种数. #include <bits/stdc++.h> using namespace std; # ...

  7. 精读《Function Component 入门》

    1. 引言 如果你在使用 React 16,可以尝试 Function Component 风格,享受更大的灵活性.但在尝试之前,最好先阅读本文,对 Function Component 的思维模式有 ...

  8. redis基本类型和操作

    基本类型:string hash list set sorted set 添加String 类型(最基本的key,value形式) set str1 s1 获取value get str1 添加has ...

  9. html的诸多标签

    1.p和br标签 p表示段落,默认段落之间是有间隔的! br是换行 hr是一条水平线 2.a标签,超链接 <a href="http://www.baidu.com" tar ...

  10. java retry:详解

    发现 今天在探秘线程池原理知识点,在阅读JDK源码时遇到程序代码中出现如下代码,因为之前没有遇到过,于是特地记录下来并谷歌了一番,后面我自己做了一些简要的验证和分析. 验证 网上溜达一番发现,这ret ...