hdu2236 无题II 最大匹配 + 二分搜索
中文题目,题意大家都明白。
看到“不同的行和列”就觉得要用二分匹配来做。要求最大值与最小值的差值最小,是通过枚举边的下限和上限来完成。
枚举过程是这样的,在输入的过程可以记录下边权的最大值MAX和最小值MIN。那么他们的边权的差值的最大值为right = MAX -MIN ,最小值left =0。然后不断地增加边的下限,查找边权的差值,如果能得到完美匹配(匹配数等于n),那么就记录下这个差值。最后输出。这个搜索过程类似于最大流+二分搜索。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 const int N=105,INF=0x3f3f3f3f; 8 int Map[N][N],cx[N],cy[N],dx[N],dy[N]; 9 bool bmask[N],bmap[N][N]; 10 int nx,ny,dis,ans; 11 bool searchpath() 12 { 13 queue<int> q; 14 dis=INF; 15 memset(dx,-1,sizeof(dx)); 16 memset(dy,-1,sizeof(dy)); 17 for(int i=1;i<=nx;i++) 18 { 19 if(cx[i]==-1){ q.push(i); dx[i]=0; } 20 while(!q.empty()) 21 { 22 int u=q.front(); q.pop(); 23 if(dx[u]>dis) break; 24 for(int v=1;v<=ny;v++) 25 { 26 if(bmap[u][v]&&dy[v]==-1) 27 { 28 dy[v]= dx[u] + 1; 29 if(cy[v]==-1) dis=dy[v]; 30 else 31 { 32 dx[cy[v]]= dy[v]+1; 33 q.push(cy[v]); 34 } 35 } 36 } 37 } 38 } 39 return dis!=INF; 40 } 41 int findpath(int u) 42 { 43 for(int v=1;v<=ny;v++) 44 { 45 if(!bmask[v]&&bmap[u][v]&&dy[v]==dx[u]+1) 46 { 47 bmask[v]=1; 48 if(cy[v]!=-1&&dy[v]==dis) continue; 49 if(cy[v]==-1||findpath(cy[v])) 50 { 51 cy[v]=u; cx[u]=v; 52 return 1; 53 } 54 } 55 } 56 return 0; 57 } 58 void maxmatch() 59 { 60 ans=0; 61 memset(cx,-1,sizeof(cx)); 62 memset(cy,-1,sizeof(cy)); 63 while(searchpath()) 64 { 65 memset(bmask,0,sizeof(bmask)); 66 for(int i=1;i<=nx;i++) 67 if(cx[i]==-1) ans+=findpath(i); 68 } 69 } 70 void init() 71 { 72 memset(bmap,0,sizeof(bmap)); 73 } 74 75 int main() 76 { 77 //freopen("test.txt","r",stdin); 78 int i,j,k,n,cas,a,b; 79 scanf("%d",&cas); 80 while(cas--) 81 { 82 scanf("%d",&n); 83 a=100,b=0; 84 for(i=1;i<=n;i++) 85 for(j=1;j<=n;j++){ 86 scanf("%d",&Map[i][j]); 87 a=min(a,Map[i][j]); 88 b=max(b,Map[i][j]); 89 } 90 nx=ny=n; 91 int L=0,R=b-a,mid,flag,res; 92 while(L<=R) 93 { 94 mid=(L+R)/2; 95 flag=0; 96 for(k=a;k<=b;k++) 97 { 98 for(i=1;i<=n;i++) 99 for(j=1;j<=n;j++) 100 if(Map[i][j]>=k&&Map[i][j]<=k+mid) bmap[i][j]=1; 101 else bmap[i][j]=0; 102 maxmatch(); 103 if(ans==n) {flag=1;break;} 104 } 105 if(flag) {res=mid;R=mid-1;} 106 else L=mid+1; 107 } 108 printf("%d\n",res); 109 } 110 return 0; 111 }
View Code
转载于:https://www.cnblogs.com/Potato-lover/p/3989675.html
hdu2236 无题II 最大匹配 + 二分搜索相关推荐
- HDOJ---2236 无题II[二分枚举+匈牙利]
无题II Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- 解题报告 (九) 二分图最大匹配
文章目录 二分图最大匹配 解题报告 一.最大匹配模板题 HDU 1083 Courses HDU 2063 过山车 HDU 1528 Card Game Cheater HDU 1179 Olliva ...
- kk_想要学习的知识
2018/4/27 计算几何 一.简介 计算几何属于ACM算法中比较冷门的分类,在省赛中只在前几年考察过,这两年还没有考过,而且和高精度计算一样,遇到题目主要靠套模板,因此对题意的理解至关重要,而且往 ...
- ACM比赛经验、刷题记录及模板库总结(更新中)
前言 本文所提及的部分题目代码,可以在我的Github上找到 第一部分 经验分享及感受 第二部分 刷题记录 一.基础算法&程序语言 //strlen()函数的复杂度是O(n)要小心 //截取字 ...
- 【HDOJ图论题集】【转】
1 =============================以下是最小生成树+并查集====================================== 2 [HDU] 3 1213 How ...
- 一系列图论问题[转]
=============================以下是最小生成树+并查集====================================== [HDU] 1213 How Many ...
- 【转载】图论 500题——主要为hdu/poj/zoj
转自--http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...
- 杭电OJ分类题目(4)-Graph
原题出处:HDOJ Problem Index by Type,http://acm.hdu.edu.cn/typeclass.php 杭电OJ分类题目(4) HDU Graph Theory - U ...
- 图论练习题(存起来练)
=============================以下是最小生成树+并查集====================================== [HDU] 1213 How Man ...
最新文章
- php中query()作用,query()方法
- linux冒泡算法程序,用蛮力法解决冒泡排序 - linux-tao的个人空间 - OSCHINA - 中文开源技术交流社区...
- 快速学习AJAX之三 Ajax实现登陆
- C++ Primer Plus 第一章 预备知识
- Badger DAO公布系统乘数奖励机制,新增时间加权奖励
- KDE桌面没有wifi的解决方案
- 开源 java CMS - FreeCMS1.9发布。
- 常用Feed流架构实现
- 关于tomcat那些事情 - tomcat6.0 配置ip地址访问不用加端口和项目名
- java面向接口编程详解
- 淘淘商城系列——VMware添加已配置好的虚拟机
- 研华工控机改软PLC使用教程
- 奇异网盘点全球10大最荒诞的“时髦”事件
- 构建 Web 应用之 Service Worker 初探
- jsp学生考勤信息系统
- Android中65536问题剖析
- 360极速浏览器屏蔽百度广告
- ubuntu 桌面菜单栏和任务栏程序标题栏消失的恢复方法
- 深度学习从入门到精通——生成对抗网络原理
- 问题解决:“nginx: [emerg] unknown directive “ “ in /etc/nginx/conf.d/XXX.conf:122”