题意:n*n的棋盘上有n枚棋子。现在要让你以最小的步数把棋盘分隔开(可以是横竖着的五个一排, 也可以是两个对角线)。问你最小步数

思路:首先枚举各个最终状态起始状态与最终状态建边权值为花费的负数,然后求最大权匹配去一下最大值。最后答案再取相反数。

代码如下:

  1 /**************************************************
  2  * Author     : xiaohao Z
  3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
  4  * Last modified : 2014-02-25 19:54
  5  * Filename     : uva_1045.cpp
  6  * Description     :
  7  * ************************************************/
  8
  9 #include <iostream>
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <cstdlib>
 13 #include <cmath>
 14 #include <algorithm>
 15 #include <queue>
 16 #include <stack>
 17 #include <vector>
 18 #include <set>
 19 #include <map>
 20 #define MP(a, b) make_pair(a, b)
 21 #define PB(a) push_back(a)
 22
 23 using namespace std;
 24 typedef long long ll;
 25 typedef pair<int, int> pii;
 26 typedef pair<unsigned int,unsigned int> puu;
 27 typedef pair<int, double> pid;
 28 typedef pair<ll, int> pli;
 29 typedef pair<int, ll> pil;
 30
 31 const int INF = 0x3f3f3f3f;
 32 const double eps = 1E-6;
 33 const int LEN = 101;
 34 int nx, ny, Map[LEN][LEN], n;
 35 int link[LEN], lx[LEN], ly[LEN], slack[LEN], visx[LEN], visy[LEN];
 36 struct P{int x, y;}p[LEN];
 37
 38 //template from kuangbin
 39 int dfs(int x){
 40     visx[x] = 1;
 41     for(int y=0; y<ny; y++){
 42         if(visy[y]) continue;
 43         int tmp = lx[x] + ly[y] - Map[x][y];
 44         if(!tmp){
 45             visy[y] = 1;
 46             if(link[y] < 0 || dfs(link[y])){
 47                 link[y] = x;
 48                 return true;
 49             }
 50         }else if(slack[y] > tmp) slack[y] = tmp;
 51     }
 52     return false;
 53 }
 54
 55 int KM(){
 56     memset(link, -1, sizeof link);
 57     memset(ly, 0, sizeof ly);
 58     for(int i=0; i<nx; i++){
 59         lx[i] = -INF;
 60         for(int j=0; j<ny; j++)
 61             if(Map[i][j] > lx[i]) lx[i] = Map[i][j];
 62     }
 63     for(int x=0; x<nx; x++){
 64         for(int i=0; i<ny; i++) slack[i] = INF;
 65         while(true){
 66             memset(visx, 0, sizeof visx);
 67             memset(visy, 0, sizeof visy);
 68             if(dfs(x)) break;
 69             int d = INF;
 70             for(int i=0; i<ny; i++)
 71                 if(!visy[i] && d > slack[i]) d = slack[i];
 72             for(int i=0; i<nx; i++) if(visx[i]) lx[i] -= d;
 73             for(int i=0; i<ny; i++){
 74                 if(visy[i]) ly[i] += d;
 75                 else slack[i] -= d;
 76             }
 77         }
 78     }
 79     int ret = 0;
 80     for(int i=0; i<ny; i++)
 81         if(link[i] != -1) ret += Map[link[i]][i];
 82     return ret;
 83 }
 84
 85 inline int dis(int a, int b, int c, int d){return abs(a-c) + abs(b-d);}
 86
 87 int main()
 88 {
 89 //    freopen("in.txt", "r", stdin);
 90
 91     int kase = 1;
 92     while(scanf("%d", &n)!=EOF && n){
 93         nx = ny = n;
 94         for(int i=0; i<n; i++){
 95             scanf("%d%d", &p[i].x, &p[i].y);
 96             p[i].x--;p[i].y--;
 97         }
 98         int ans = -INF;
 99         //row
100         for(int i=0; i<n; i++){
101             memset(Map, 0x3f, sizeof Map);
102             for(int j=0; j<n; j++)
103                 for(int k=0; k<n; k++){
104                     Map[j][k] = -dis(p[j].x, p[j].y, i, k);
105                 }
106             ans = max(ans, KM());
107         }
108         //col
109         for(int i=0; i<n; i++){
110             memset(Map, 0x3f, sizeof Map);
111             for(int j=0; j<n; j++)
112                 for(int k=0; k<n; k++)
113                     Map[j][k] = -dis(p[j].x, p[j].y, k, i);
114             ans = max(ans, KM());
115         }
116         //
117         memset(Map, 0x3f, sizeof Map);
118         for(int i=0; i<n; i++)
119             for(int j=0; j<n; j++){
120                 Map[i][j] = -dis(p[i].x, p[i].y, j, j);
121             }
122         ans = max(ans, KM());
123         memset(Map, 0x3f, sizeof Map);
124         for(int i=0; i<n; i++)
125             for(int j=0; j<n; j++)
126                 Map[i][j] = -dis(p[i].x, p[i].y, j, n-j-1);
127         ans = max(ans, KM());
128         ans = -ans;
129         printf("Board %d: %d moves required.\n\n", kase++, ans);
130     }
131     return 0;
132 }

View Code

转载于:https://www.cnblogs.com/shu-xiaohao/p/3567668.html

uva 1045(二分图最大权匹配)相关推荐

  1. 【算法笔记】二分图最大权匹配 - KM算法(dfs版O(n4) + bfs版O(n3))

    整理的算法模板合集: ACM模板 匈牙利算法又称为 KM 算法,可以在 O(n3)O(n^3)O(n3) 时间内求出二分图的 最大权完美匹配 . 考虑到二分图中两个集合中的点并不总是相同,为了能应用 ...

  2. UOJ#80 二分图最大权匹配 [模板题]

    从前一个和谐的班级,有 nlnl 个是男生,有 nrnr 个是女生.编号分别为 1,-,nl1,-,nl 和 1,-,nr1,-,nr. 有若干个这样的条件:第 vv 个男生和第 uu 个女生愿意结为 ...

  3. 二分图最大权匹配 KM算法

    KM算法的正确性基于以下定理: 若由二分图中所有满足A[i]+B[i]=w[i][j]的边C(i,j)构成的子图(即相等子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配 基本概念 1.完备匹配 ...

  4. BZOJ 1937: [Shoi2004]Mst 最小生成树 [二分图最大权匹配]

    传送门 题意: 给一张无向图和一棵生成树,改变一些边的权值使生成树为最小生成树,代价为改变权值和的绝对值,求最小代价 线性规划的形式: $Min\quad \sum\limits_{i=1}^{m} ...

  5. 二分图最大权匹配问题KM算法讲解 HDU 2255 奔小康赚大钱

    作者:logosG 链接:https://www.cnblogs.com/logosG/p/logos.html (讲解的KM算法,特别厉害!!!) KM算法: 现在我们来考虑另外一个问题:如果每个员 ...

  6. HDU - 2255 奔小康赚大钱(二分图最大权匹配+KM)

    题目链接:点击查看 题目大意:中文题目,简单来说就是n个人和n个房子最大匹配,需要一一对应并且满足权值和最大 题目分析:二分图的完备匹配,条件完全符合KM算法的局限性,直接套模板即可,后续学习费用流( ...

  7. uva 11383(二分图最大权匹配)

    题意:一个n*n的矩阵每个格子里有一个正整数w(i,j)你的任务是确定每行一个整数row(i)每列一个整数col(i),对每个格子都有w(i,j)<=row(i)+col(j)所有row(i)和 ...

  8. 【图】二分图最大权匹配

    近代数学选讲的作业,写了五个小时(大部分参考<图论与网络最优化算法>龚劬 编),由于word公式直接粘来会出来乱码所以保存成了图片格式,凑合看吧~~~

  9. 二分图最大匹配及最大权匹配

    二分图最大匹配学习 一.二分图的基本知识 二.二分图最大匹配 什么是二分图最大匹配 怎么求二分图最大匹配 三.二分图最大权匹配 四.例题训练 三.最小点覆盖数 一位大佬的神级解释 本以为有了网络流,就 ...

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

    题目大意:给出棋盘上的N个点的位置.如今问将这些点排成一行或者一列.或者对角线的最小移动步数(每一个点都仅仅能上下左右移动.一次移动一个) 解题思路:暴力+二分图最佳完美匹配 #include < ...

最新文章

  1. 数据库设计的三大范式
  2. 全网最详细之一网打尽数据结构中与树相关的算法
  3. ISE中使用Notepad++的关联设置以及Notepad++的护眼设置(设置背景色)
  4. php弹出消息翻页,一个很不错的PHP翻页类
  5. Algorithm之OP:OP之GA遗传算法思路理解相关配图资料
  6. 重整谋定电商经信研究新格局-李玉庭:人工智能精细化运营
  7. 90后码农可以拯救互联网吗?
  8. 03:数据结构 栈、队列、链表与数组
  9. 下拉菜单(含有阻止事件冒泡)
  10. 网关和路由器有什么区别
  11. 三端稳压7805和7905稳压原理及典型电路
  12. sql 时间日期格式转换
  13. 更换苹果推送服务证书Apple Push Services Certificate
  14. 【Excel】【行列转换:转置粘贴 or TRANSPOSE】
  15. 酒诗词之一(七言诗)
  16. 干货!最全的AI速查表|神经网络,机器学习,深度学习
  17. WATCH ME 2007
  18. mybatis从入门到精通(刘增辉著)-读书笔记第三章
  19. 【无标题】移动端App下载页面模版
  20. MIIX510(MIIX5)如何进入BIOS

热门文章

  1. Docker教程:docker machine的配置和命令
  2. python模块:调用系统命令模块subprocess等
  3. pandas.DataFrame将行(index)和列(column)进行转置
  4. 冒泡排序和选择排序的实现与比较
  5. java string 日期格式_Java 日期格式和String 转换
  6. 汇编实现冒泡法排序及优化
  7. 蓝桥杯2019年第十届C/C++省赛第六题-旋转
  8. vite+vue3 整合vue-router4和vuex4
  9. Java 笔记(二)
  10. Flutter学习 — 创建一个 grid List