题目大意:给出棋盘上的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. 二分图最佳完美匹配——KM算法总结

    KM 算法 求解二分图最佳完美匹配的算法. 先来看一道例题Hdu 2255. 显然是KM的裸题.假设我们要匹配集合X和Y的点,先给每个点一个顶标Lx和Ly. 为什么要给顶标? 首先顶标是我们限制边的一 ...

  3. 二分图最佳完美匹配——KM算法

    前情概要 学km算法之前,笔者还是希望大家已经掌握了匈牙利算法--也就是对于求解二分图最大匹配的算法.学习本算法的前提除了已经掌握C++语言之外,还需要掌握邻接表存图法,不会的朋友这里有传送门 [微笑 ...

  4. 图论--二分图最佳完美匹配(KM模板)

    #include <iostream> #include <cstring> #include <cstdio>using namespace std; const ...

  5. 二分图的最佳完美匹配(模板)

    二分图的最佳完美匹配,也就是带权值的无向二分图中权值之和最大的完美匹配,整个图分为两个不相交的集合x和y,采用KM算法求解,也称匈牙利算法. 时间复杂度为O(n^3) typedef int type ...

  6. UVA-1045 - The Great Wall Game(二分图最佳匹配)

    题意:在一个n*n的棋盘上有n个棋子,要求通过移动棋子使棋子的排布满足以下情况之一:呈横行排列:呈纵行排列:呈对角线排列(有两条). 棋子移动一个单元格的费用为1,总费用为所有棋子的移动费用之和.求最 ...

  7. hdu-3488-Tour(KM最佳完美匹配)

    题意:有N个城市,M条街道,每条街道是单向的,现在要你设计多条路线覆盖所有的点,每条路线都是一个环,并且每个点仅能被一条路线覆盖且只经过一次(终始点除外) 分析:因为是有向圈,所以每个点的入度和出度应 ...

  8. Uvalive 4043 - Ants(二分图完美匹配)

    题目链接 https://vjudge.net/problem/UVALive-4043 [题意]        给出n个白点和n个黑点的坐标,要求用n条不相交的线段把它们连起来,其中每条线段恰好连接 ...

  9. 【HDU 2255】奔小康赚大钱 (最佳二分匹配KM算法)

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

最新文章

  1. JavaScript语言基础10
  2. Chrome 解决flash问题
  3. 笔记本的处理器型号怎么区别好坏
  4. 操作系统课设--系统调用
  5. MySQL创建普通用户
  6. 国内三款主流海淘产品APP竞品分析
  7. js+css 使div背景图在ie6中透明
  8. 《MFC游戏开发》笔记八 游戏特效的实现(二):粒子系统
  9. JFinal源码解析--从请求到处理返回流程
  10. 安装centos 6.5
  11. jdk环境变量的配置
  12. jmeter 连接mysql数据库
  13. 西瓜创客的python_西瓜创客Python客户端
  14. b和kb的换算_b和mb的换算(b kb mb换算)
  15. python怎么变成竖行_用python实现古诗词横板竖版显示 【二维列表的使用】
  16. 计算机的rom与硬盘区别,RAM和ROM亲们傻傻分不清?
  17. 单臂路由配置-ZTE中兴交换机
  18. 什么是似然函数?是条件概率吗?
  19. 计算机主机与外部交换的部件是,主机与外部设备的信息交换.PPT
  20. Unreal Engine 4 初学者教程:开始

热门文章

  1. python xml字符串和dict字典互转
  2. cap = cv2.VideoCapture(0).read()摄像头读取图片用法
  3. Tensorflow mnist 数据集测试代码 + 自己下载数据
  4. Network In Network
  5. LLVM系列文章1: Debian/Ubuntu 安装和使用 LLVM
  6. Linux测试服务器端口号是否可以成功访问
  7. pycharm中R工具包的安装
  8. @ImportResource-SpringBoot使用xml配置Bean
  9. Docker(三):Docker 镜像使用
  10. iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)