博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu2236 无题II 最大匹配 + 二分搜索
阅读量:4640 次
发布时间:2019-06-09

本文共 2362 字,大约阅读时间需要 7 分钟。

  中文题目,题意大家都明白。

  看到“不同的行和列”就觉得要用二分匹配来做。要求最大值与最小值的差值最小,是通过枚举边的下限和上限来完成。

  枚举过程是这样的,在输入的过程可以记录下边权的最大值MAX和最小值MIN。那么他们的边权的差值的最大值为right = MAX -MIN ,最小值left =0。然后不断地增加边的下限,查找边权的差值,如果能得到完美匹配(匹配数等于n),那么就记录下这个差值。最后输出。这个搜索过程类似于最大流+二分搜索。

1 #include
2 #include
3 #include
4 #include
5 #include
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
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

你可能感兴趣的文章
linux下面升级 Python版本并修改yum属性信息
查看>>
局域网内通讯APP
查看>>
Unity Shader 图片流光效果实现(纯计算方式)
查看>>
POJ 2002 Squares
查看>>
Java 内存分配
查看>>
ObjectDataSource控件执行Delete操作时,出现“未能找到带参数的非泛型方法”的解决方案...
查看>>
Ubuntu17.10 React Native 环境搭建
查看>>
Atitit 基于sql编程语言的oo面向对象大规模应用解决方案attilax总结
查看>>
jQuery-2.1.4.min.js:4 Uncaught TypeError: Illegal invocation
查看>>
jvm-监控指令-jdump
查看>>
maven安装与配置
查看>>
偶记:mysql5.7的官方doc也有错误啊:写的是vc runtime 2010,但实际上必须是 vc runtime 2013。坑...
查看>>
费马小定理,欧拉定理,指数循环节
查看>>
数据类型以的相互转化及赋值操作符,常用数学函数
查看>>
React-Redux之API
查看>>
bzoj千题计划266:bzoj4872: [六省联考2017]分手是祝愿
查看>>
jquery显示隐藏操作
查看>>
JAVA基础-数组
查看>>
【区间DP】能量项链
查看>>
trove 开发者阅读翻译
查看>>