思路大概同bzoj2395(传送门:http://www.cnblogs.com/DUXT/p/5739864.html),还是将每一种匹配方案的Σai看成x,Σbi看成y,然后将每种方案转化为平面上的点,再用km去找最远的点就行了。

然而几个月前就学过km且到现在还未写过一道km的题的我并不知道km如何对于负权给出最优解。。。。

#define XX 某传统算法(例如:最小生成树,二分图最优带权匹配什么的)

顺便总结一下最小乘积XX

即对于XX引入两个权值的概念(或是多个权值,一般是两个),看似无从下手,却可以将每一组可行解的方案的两个sum转化为平面内一个点,然后就可以发现一个十分优美的性质即最优解一定在凸包上,于是可以利用一种类似于快包算法的算法,依旧是用XX找出一定在凸包上的两个点,然后再次利用XX进行分治,递归地下去找,弄清楚边界条件(一般一个叉乘就可以轻松搞定),这样问题就被轻易地解决了。(貌似知道了这样的一个模板,基本所有类似问题都可以得到解决)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 100
#define inf 100000000 int cases,n;
int a[maxn][maxn],b[maxn][maxn],val[maxn][maxn],slack[maxn],valx[maxn],valy[maxn],linky[maxn];
bool visx[maxn],visy[maxn]; struct point{
int x,y;
}ans; point operator -(point a,point b){return(point){a.x-b.x,a.y-b.y};}
double operator *(point a,point b){return a.x*b.y-a.y*b.x;} bool find(int x){
visx[x]=;
for (int y=;y<=n;y++)
if (!visy[y]){
int t=valx[x]+valy[y]-val[x][y];
if (!t){
visy[y]=;
if (!linky[y]||find(linky[y])){
linky[y]=x;
return ;
}
}
else slack[y]=min(slack[y],t);
}
return ;
} point km(){
memset(valx,,sizeof(valx));
memset(valy,,sizeof(valy));
memset(linky,,sizeof(linky));
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
valx[i]=max(valx[i],val[i][j]);
for (int x=;x<=n;x++){
memset(slack,,sizeof(slack));
while (){
memset(visx,,sizeof(visx));
memset(visy,,sizeof(visy));
if (find(x)) break;
int d=inf;
for (int i=;i<=n;i++) if (!visy[i]) d=min(d,slack[i]);
for (int i=;i<=n;i++) if (visx[i]) valx[i]-=d;
for (int i=;i<=n;i++) if (visy[i]) valy[i]+=d;
}
}
point now={,};
for (int i=;i<=n;i++) now.x+=a[linky[i]][i],now.y+=b[linky[i]][i];
if ((ans.x==inf&&ans.y==inf)||(ans.x*ans.y>now.x*now.y)) ans=now;
return now;
} bool operator ==(point a,point b){return a.x==b.x&&a.y==b.y;} void solve(point x,point y){
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
val[i][j]=b[i][j]*(x.x-y.x)+a[i][j]*(y.y-x.y);
point z=km();
if ((z-x)*(y-z)<=) return;
solve(x,z);
solve(z,y);
} int main(){
scanf("%d",&cases);
while (cases--){
scanf("%d",&n);
ans.x=ans.y=inf;
for (int i=;i<=n;i++)
for (int j=;j<=n;j++) scanf("%d",&a[i][j]);
for (int i=;i<=n;i++)
for (int j=;j<=n;j++) scanf("%d",&b[i][j]);
point minx,miny;
for (int i=;i<=n;i++)
for (int j=;j<=n;j++) val[i][j]=-a[i][j];
minx=km();
for (int i=;i<=n;i++)
for (int j=;j<=n;j++) val[i][j]=-b[i][j];
miny=km();
solve(minx,miny);
printf("%d\n",ans.x*ans.y);
}
return ;
}

bzoj3571: [Hnoi2014]画框 最小乘积匹配+最小乘积XX总结,的更多相关文章

  1. BZOJ3571 [Hnoi2014]画框 【分治 + KM算法】

    题目链接 BZOJ3571 题解 如果知道最小乘积生成树,那么这种双权值乘积最小就是裸题了 将两权值和作为坐标,转化为二维坐标系下凸包上的点,然后不断划分分治就好了 这里求的是最小匹配值,每次找点套一 ...

  2. BZOJ3571 : [Hnoi2014]画框

    题目是要求最小乘积最小权匹配, 将一种方案看做一个二维点(x,y),x=a值的和,y=b值的和,所有方案中只有在下凸壳上的点才有可能成为最优解 首先要求出两端的方案l,r两个点 l就是a值的和最小的方 ...

  3. 【算法】最小乘积生成树 & 最小乘积匹配 (HNOI2014画框)

    今天考试的时候果然题目太难于是我就放弃了……转而学习了一下最小乘积生成树. 最小乘积生成树定义: (摘自网上一篇博文). 我们主要解决的问题就是当k = 2时,如何获得最小的权值乘积.我们注意到一张图 ...

  4. BZOJ 3571 [Hnoi2014]画框(最小乘积完美匹配)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3571 [题目大意] 给出一张二分图,每条边上有a,b两个值,求完美匹配, 使得suma ...

  5. bzoj3571————2016——3——12(最小乘积匹配)

    bzoj3571 传送门http://www.lydsy.com/JudgeOnline/problem.php?id=3571 题解: ——————来自伟大的thy大神  http://blog.c ...

  6. GCJ:2008 Round1AA-Minimum Scalar Product(有序数组倒序乘积和最小)

    题目链接:https://code.google.com/codejam/contest/32016/dashboard#s=p0 Minimum Scalar Product This contes ...

  7. BZOJ3571 & 洛谷3236:[HNOI2014]画框——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3571 https://www.luogu.org/problemnew/show/P3236 小T ...

  8. nyoj 237 游戏高手的烦恼 二分匹配--最小点覆盖

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=237 二分匹配--最小点覆盖模板题 Tips:用邻接矩阵超时,用数组模拟邻接表WA,暂时只 ...

  9. HDU(1853),最小权匹配,KM

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853 Cyclic Tour Time Limit: 1000/1000 MS (Java/Other ...

随机推荐

  1. 基础 HTML之目录问题(相对路径和绝对路径区别)

    一.相对路径和绝对路径 相对路径:以引用文件之网页所在位置为参考基础,而建立出的目录路径.因此,当保存于不同目录的网页引用同一个文件时,所使用的路径将不相同,故称之为相对. 绝对路径:以Web站点根目 ...

  2. 【转】Vim 常用命令总结

    使用 Vim 的时间不长,但如今已经离不开熟悉的 Vim 编辑模式了. Vim 的学习曲线是非常陡的,一开始学习的时候,面对很多的操作命令要去记住,常常望而却步. 其实,只要记住一些常用的命令,加之在 ...

  3. 教程-Delphi操作快捷键

    ************************************************************** Delphi快捷键-全-高手用-南山古桃(新手)-同学共进 ******* ...

  4. A Tour of Go For continued

    As in C or Java, you can leave the pre and post statements empty. package main import "fmt" ...

  5. [一]初识Ajax

    是什么? 一种网页交换数据的技术 作用: 使页面局部刷新,获取后台数据 怎么做? 调用浏览器内置对象发送异步请求

  6. 库不存在的排查方法:ImportError: No module named selenium2Library

    解决办法: 把selenium2Library改成Selenium2Library   安装下面四个: python-2.7.13.amd64.msi robotframework-ride-1.5. ...

  7. MySQL 5.7 for Windows 解压缩版 MySQL 服务无法启动

    MySQL 5.7 for Windows 解压缩版配置安装 http://jingyan.baidu.com/article/f3ad7d0ffc061a09c3345bf0.html basedi ...

  8. [ATL/WTL]_[0基础]_[CBitmap复制图片-截取图片-平铺图片]

    场景: 1.当你须要截取图片部分区域作为某个控件的背景. 2.须要平铺图片到一个大区域让他自己主动放大时. 3.或者须要合并图片时. 代码: CDC sdc; CDC ddc; sdc.CreateC ...

  9. [React] React Fundamentals: Mixins

    Mixins will allow you to apply behaviors to multiple React components. Components are the best way t ...

  10. CleanMyMac 1.10.8

    CleanMyMac是一个系统清理工具,删除系统缓存文件 , 多余的应用程序语言包 , PowerPc软件运行库等. 是个给你的硬盘瘦身的好工具 下载地址:http://soft.macx.cn/so ...