传送门

我们把一种方案的\(\sum a_{i,j}\)和\(\sum b_{i,j}\)看成点\((\sum a_{i,j},\sum b_{i,j})\),那么就只要求横纵坐标之积最小的点,类似于最小乘积生成树

首先跑出\(\sum a_{i,j}\)最小和\(\sum b_{i,j}\)最小的,得到的点记为\(A\)和\(B\),然后求一个在\(AB\)左侧,距离\(AB\)最远的点\(C\).这就相当于要最大化\(S_{\triangle ABC}=|\frac{\vec{AB}\times\vec{AC}}{2}|\),因为\(C\)在\(AB\)左侧,所以是要最小化

\[\begin{matrix}\vec{AB}\times\vec{AC} &= (x_B-x_A)*(y_C-y_A)-(y_B-y_A)*(x_C-x_A)\\ &= (x_B-x_A)*y_C+(y_A-y_B)*x_C+S\end{matrix}
\]

\((S为常数项)\)

所以把\((x_B-x_A)*b_{i,j}+(y_A-y_B)*a_{i,j}\)设为边权,跑KM就好了,如果找到这样的点就继续递归处理\(AC\)和\(CB\),注意如果叉积\(\ge 0\),那么不在左侧,退出

话说二分图最小权匹配只要边权取反就好了,我沙雕还把其他地方跟着改了,WA的捕星

#include<bits/stdc++.h>
#define LL long long
#define db double
#define il inline
#define re register using namespace std;
const int N=75;
il int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int n,a[N][N],b[N][N],mat[N],va[N],vb[N],e[N][N],sl[N],pr[N];
bool v[N];
void xyl(int xx)
{
memset(sl,0x3f3f3f,sizeof(sl));
memset(v,0,sizeof(v));
memset(pr,0,sizeof(pr));
int p=0;
mat[p]=xx;
do
{
int x=mat[p],mi=sl[0],nxt;
v[p]=1;
for(int y=1;y<=n;++y)
if(!v[y])
{
if(sl[y]>va[x]+vb[y]-e[x][y]) sl[y]=va[x]+vb[y]-e[x][y],pr[y]=p;
if(mi>sl[y]) mi=sl[y],nxt=y;
}
for(int i=0;i<=n;++i)
{
if(v[i]) va[mat[i]]-=mi,vb[i]+=mi;
else sl[i]-=mi;
}
p=nxt;
}while(mat[p]);
while(p) mat[p]=mat[pr[p]],p=pr[p];
}
int ans;
void dc(int ax,int ay,int bx,int by)
{
if(ay<by||(ay==by&&ax>bx)) swap(ax,bx),swap(ay,by);
int cx=0,cy=0;
for(int i=1;i<=n;++i)
{
va[i]=vb[i]=0;
for(int j=1;j<=n;++j)
va[i]=max(va[i],e[i][j]=-((bx-ax)*b[i][j]+(ay-by)*a[i][j]));
}
memset(mat,0,sizeof(mat));
for(int i=1;i<=n;++i) xyl(i);
for(int j=1;j<=n;++j) cx+=a[mat[j]][j],cy+=b[mat[j]][j];
ans=min(ans,cx*cy);
if((bx-ax)*(cy-ay)-(by-ay)*(cx-ax)<0) dc(ax,ay,cx,cy),dc(cx,cy,bx,by);
} int main()
{
int T=rd();
while(T--)
{
n=rd();
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
a[i][j]=rd();
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
b[i][j]=rd();
int ax=0,ay=0,bx=0,by=0;
for(int i=1;i<=n;++i)
{
va[i]=vb[i]=0;
for(int j=1;j<=n;++j)
va[i]=max(va[i],e[i][j]=-a[i][j]);
}
memset(mat,0,sizeof(mat));
for(int i=1;i<=n;++i) xyl(i);
for(int j=1;j<=n;++j) ax+=a[mat[j]][j],ay+=b[mat[j]][j];
for(int i=1;i<=n;++i)
{
va[i]=vb[i]=0;
for(int j=1;j<=n;++j)
va[i]=max(va[i],e[i][j]=-b[i][j]);
}
memset(mat,0,sizeof(mat));
for(int i=1;i<=n;++i) xyl(i);
for(int j=1;j<=n;++j) bx+=a[mat[j]][j],by+=b[mat[j]][j];
ans=min(ax*ay,bx*by);
dc(ax,ay,bx,by);
printf("%d\n",ans);
}
return 0;
}

luogu P3236 [HNOI2014]画框的更多相关文章

  1. 洛谷P3236 [HNOI2014]画框(最小乘积KM)

    题面 传送门 题解 我似乎连\(KM\)都不会打啊→_→ 和bzoj2395是一样的,只不过把最小生成树换成\(KM\)了.因为\(KM\)跑的是最大权值所以取个反就行了 //minamoto #in ...

  2. 【LG3236】[HNOI2014]画框

    [LG3236][HNOI2014]画框 题面 洛谷 题解 和这题一模一样. 将最小生成树换成\(KM\)即可. 关于复杂度,因为决策点肯定在凸包上,且\(n\)凸包的期望点数为\(\sqrt {\l ...

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

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

  4. bzoj 3571: [Hnoi2014]画框

    Description 小T准备在家里摆放几幅画,为此他买来了N幅画和N个画框.为了体现他的品味,小T希望能合理地搭配画与画框,使得其显得既不过于平庸也不太违和.对于第 幅画与第 个画框的配对,小T都 ...

  5. [HNOI2014]画框

    题目描述 小T准备在家里摆放几幅画,为此他买来了N幅画和N个画框.为了体现他的品味,小T希望能合理地搭配画与画框,使得其显得既不过于平庸也不太违和. 对于第 幅画与第 个画框的配对,小T都给出了这个配 ...

  6. Luogu 3233 [HNOI2014]世界树

    BZOJ 3572 首先看出虚树,然后考虑如何$dp$. 我们先在处理出的虚树上$dp$一遍,处理出虚树上所有点距离最近的关键点(关键点一定在虚树上嘛). 具体来说,先搜一遍处理出每一个点的父亲到它的 ...

  7. BZOJ3571 : [Hnoi2014]画框

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

  8. bzoj3571: [Hnoi2014]画框 最小乘积匹配+最小乘积XX总结,

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

  9. luogu P3238 [HNOI2014]道路堵塞

    传送门 这什么题啊,乱搞就算了,不知道SPFA已经死了吗 不对那个时候好像还没死 暴力就是删掉边后跑Dijkstra SPFA 然后稍微分析一下,可以发现题目中要求的不经过最短路某条边的路径,一定是先 ...

随机推荐

  1. js 正则表达式的使用(标志 RegExp exec() test() compile() $1...$9)

    一,标志 g (global,全局匹配标志) 执行正则表达式匹配或替换时,一般只要搜索到一个符合的文本就停止匹配或替换.使用该标志将搜索所有符合的文本直到文本末尾. i (ignoreCase,忽略大 ...

  2. firfox中"content-disposition", "attachment;filename=“+filename不能显示文件名字

    一般要在浏览器中显示文件名,可以使用以下文件名 // 设置文件名的编码方式,使得文件的名字能够正常安全的显示. filename = URLEncoder.encode(filename, " ...

  3. unittest的使用二——生成基于html的测试报告

    mac下的安装: 1.下载HTMLTestRunner.py文件,下载地址http://tungwaiyip.info/software/HTMLTestRunner.html,可以复制里面的内容到一 ...

  4. 数据库 价格字段 设置 decimal(8,2),价格为100W,只显示999999.99

    DECIMAL(M,D),M是数字最大位数,D是小数点右侧数字个数,整数M-D位 decimal(8,2)数值范围是 -999999.99 ~ 999999.99 1000000超过了6位,严格模式下 ...

  5. 【清北学堂2018-刷题冲刺】Contest 5

     这三个题写了一天半,第一个题写了大概一整天.出题人劝我从后往前写,我不听,结果T1想了+调了一天QWQWQ Task 1:序列 [问题描述]  定义一个"好的序列"为一个长度为M ...

  6. python: with的使用;

    with适用于对资源进行访问的场合,不论使用过程中是否发生异常都执行必要的“清理”操作,释放资源,比如文件资源的关闭,线程锁的获取和释放等: with与上下文管理器相关: 上下文管理协议:  包含__ ...

  7. CentOS6.9快速安装配置svn

    CentOS6.9快速安装配置svn 环境介绍: 操作系统:CentOS release 6.9 (Final)192.168.65.130 (svn服务器)192.168.65.129 (svn客户 ...

  8. mysql存储过程造数据取一个基准用户的各种类型都取一条数据作为基准数据,循环插入

    CREATE DEFINER=`user`@`%` PROCEDURE `create_upload_data`(in start_userid integer,in create_counter i ...

  9. 用go实现一个redis-cli

    转载文章:https://my.oschina.net/liangwt/blog/2231557?origin= 代码样例:https://github.com/liangwt/redis-cli

  10. Unity-使用面向对象的思想

    在做游戏之初,老师曾经说过要用面向对象的思想去做.当时满口答应,应为学了一点C#的原因感觉面向对象很简单嘛,但是事实上在做游戏的过程中,为了赶进度我的代码写的很冗余,很乱.这就导致了我不得不重新修改. ...