uva 1045(二分图最大权匹配)
题意: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(二分图最大权匹配)相关推荐
- 【算法笔记】二分图最大权匹配 - KM算法(dfs版O(n4) + bfs版O(n3))
整理的算法模板合集: ACM模板 匈牙利算法又称为 KM 算法,可以在 O(n3)O(n^3)O(n3) 时间内求出二分图的 最大权完美匹配 . 考虑到二分图中两个集合中的点并不总是相同,为了能应用 ...
- UOJ#80 二分图最大权匹配 [模板题]
从前一个和谐的班级,有 nlnl 个是男生,有 nrnr 个是女生.编号分别为 1,-,nl1,-,nl 和 1,-,nr1,-,nr. 有若干个这样的条件:第 vv 个男生和第 uu 个女生愿意结为 ...
- 二分图最大权匹配 KM算法
KM算法的正确性基于以下定理: 若由二分图中所有满足A[i]+B[i]=w[i][j]的边C(i,j)构成的子图(即相等子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配 基本概念 1.完备匹配 ...
- BZOJ 1937: [Shoi2004]Mst 最小生成树 [二分图最大权匹配]
传送门 题意: 给一张无向图和一棵生成树,改变一些边的权值使生成树为最小生成树,代价为改变权值和的绝对值,求最小代价 线性规划的形式: $Min\quad \sum\limits_{i=1}^{m} ...
- 二分图最大权匹配问题KM算法讲解 HDU 2255 奔小康赚大钱
作者:logosG 链接:https://www.cnblogs.com/logosG/p/logos.html (讲解的KM算法,特别厉害!!!) KM算法: 现在我们来考虑另外一个问题:如果每个员 ...
- HDU - 2255 奔小康赚大钱(二分图最大权匹配+KM)
题目链接:点击查看 题目大意:中文题目,简单来说就是n个人和n个房子最大匹配,需要一一对应并且满足权值和最大 题目分析:二分图的完备匹配,条件完全符合KM算法的局限性,直接套模板即可,后续学习费用流( ...
- uva 11383(二分图最大权匹配)
题意:一个n*n的矩阵每个格子里有一个正整数w(i,j)你的任务是确定每行一个整数row(i)每列一个整数col(i),对每个格子都有w(i,j)<=row(i)+col(j)所有row(i)和 ...
- 【图】二分图最大权匹配
近代数学选讲的作业,写了五个小时(大部分参考<图论与网络最优化算法>龚劬 编),由于word公式直接粘来会出来乱码所以保存成了图片格式,凑合看吧~~~
- 二分图最大匹配及最大权匹配
二分图最大匹配学习 一.二分图的基本知识 二.二分图最大匹配 什么是二分图最大匹配 怎么求二分图最大匹配 三.二分图最大权匹配 四.例题训练 三.最小点覆盖数 一位大佬的神级解释 本以为有了网络流,就 ...
- UVA - 1045 The Great Wall Game(二分图最佳完美匹配)
题目大意:给出棋盘上的N个点的位置.如今问将这些点排成一行或者一列.或者对角线的最小移动步数(每一个点都仅仅能上下左右移动.一次移动一个) 解题思路:暴力+二分图最佳完美匹配 #include < ...
最新文章
- 数据库设计的三大范式
- 全网最详细之一网打尽数据结构中与树相关的算法
- ISE中使用Notepad++的关联设置以及Notepad++的护眼设置(设置背景色)
- php弹出消息翻页,一个很不错的PHP翻页类
- Algorithm之OP:OP之GA遗传算法思路理解相关配图资料
- 重整谋定电商经信研究新格局-李玉庭:人工智能精细化运营
- 90后码农可以拯救互联网吗?
- 03:数据结构 栈、队列、链表与数组
- 下拉菜单(含有阻止事件冒泡)
- 网关和路由器有什么区别
- 三端稳压7805和7905稳压原理及典型电路
- sql 时间日期格式转换
- 更换苹果推送服务证书Apple Push Services Certificate
- 【Excel】【行列转换:转置粘贴 or TRANSPOSE】
- 酒诗词之一(七言诗)
- 干货!最全的AI速查表|神经网络,机器学习,深度学习
- WATCH ME 2007
- mybatis从入门到精通(刘增辉著)-读书笔记第三章
- 【无标题】移动端App下载页面模版
- MIIX510(MIIX5)如何进入BIOS
热门文章
- Docker教程:docker machine的配置和命令
- python模块:调用系统命令模块subprocess等
- pandas.DataFrame将行(index)和列(column)进行转置
- 冒泡排序和选择排序的实现与比较
- java string 日期格式_Java 日期格式和String 转换
- 汇编实现冒泡法排序及优化
- 蓝桥杯2019年第十届C/C++省赛第六题-旋转
- vite+vue3 整合vue-router4和vuex4
- Java 笔记(二)
- Flutter学习 — 创建一个 grid List