LOJ #2205. 「HNOI2014」画框 解题报告
#2205. 「HNOI2014」画框
最小乘积生成树+KM二分图带权匹配
维护一个\((\sum A,\sum B)\)的匹配下凸包,答案在这些点中产生。
具体的,凸包两端可以直接跑单独的\(A\)权与\(B\)权的最小带权匹配
然后进行分治,每次找离线段的最远点加入匹配
用叉积推一下式子可以得到进行匹配的图的边权,然后继续跑KM就可以了
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define yuucute 1
const int N=80;
using std::min;
using std::max;
struct Point
{
int x,y;
Point(){x=0,y=0;}
Point(int X,int Y){x=X,y=Y;}
Point friend operator -(Point a,Point b){return Point(a.x-b.x,a.y-b.y);}
};
int Cross(Point a,Point b){return a.x*b.y-a.y*b.x;}
int va[N],vb[N],w[N][N],a[N][N],b[N][N],mat[N],la[N],lb[N],n,mi,ans;
bool dfs(int now)
{
va[now]=1;
for(int v=1;v<=n;v++)
if(!vb[v])
{
if(w[now][v]==la[now]+lb[v])
{
vb[v]=1;
if(!mat[v]||dfs(mat[v]))
return mat[v]=now,true;
}
else mi=min(mi,la[now]+lb[v]-w[now][v]);
}
return false;
}
Point KM()
{
memset(mat,0,sizeof mat);
for(int i=1;i<=n;i++)
{
la[i]=-(1<<30);
lb[i]=0;
for(int j=1;j<=n;j++)
la[i]=max(la[i],w[i][j]);
}
for(int i=1;i<=n;i++)
{
while(yuucute)
{
memset(va,0,sizeof va);
memset(vb,0,sizeof vb);
mi=1<<30;
if(dfs(i)) break;
for(int j=1;j<=n;j++)
{
if(va[j]) la[j]-=mi;
if(vb[j]) lb[j]+=mi;
}
}
}
Point ret;
for(int i=1;i<=n;i++) ret.x+=a[mat[i]][i],ret.y+=b[mat[i]][i];
return ret;
}
void Divide(Point A,Point B)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
w[i][j]=a[i][j]*(B.y-A.y)-b[i][j]*(B.x-A.x);
Point C=KM();
if(Cross(C-A,B-A)<=0) return;
ans=min(ans,C.x*C.y);
Divide(A,C),Divide(C,B);
}
void work()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&b[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
w[i][j]=-a[i][j];
Point A=KM();
ans=A.x*A.y;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
w[i][j]=-b[i][j];
Point B=KM();
ans=min(ans,B.x*B.y);
Divide(A,B);
printf("%d\n",ans);
}
int main()
{
int T;scanf("%d",&T);
while(T--) work();
return 0;
}
2019.2.19
LOJ #2205. 「HNOI2014」画框 解题报告的更多相关文章
- 【LOJ】#2205. 「HNOI2014」画框
题解 我原来根本不会KM 更新每个节点增加的最小值的时候,要忽略那个方访问过的右节点!!! 然后就和最小乘积生成树一样了 代码 #include <iostream> #include & ...
- 「ZJOI2016」旅行者 解题报告
「ZJOI2016」旅行者 对网格图进行分治. 每次从中间选一列,然后枚举每个这一列的格子作为起点跑最短路,进入子矩形时把询问划分一下,有点类似整体二分 至于复杂度么,我不会阿 Code: #incl ...
- 「HNOI2016」树 解题报告
「HNOI2016」树 事毒瘤题... 我一开始以为每次把大树的子树再接给大树,然后死活不知道咋做,心想怕不是个神仙题哦 然后看题解后才发现是把模板树的子树给大树,虽然思维上难度没啥了,但是还是很难写 ...
- 「HNOI2016」序列 解题报告
「HNOI2016」序列 有一些高妙的做法,懒得看 考虑莫队,考虑莫队咋移动区间 然后你在区间内部找一个最小值的位置,假设现在从右边加 最小值左边区间显然可以\(O(1)\),最小值右边的区间是断掉的 ...
- 「HNOI2016」网络 解题报告
「HNOI2016」网络 我有一个绝妙的可持久化树套树思路,可惜的是,它的空间是\(n\log^2 n\)的... 注意到对一个询问,我们可以二分答案 然后统计经过这个点大于当前答案的路径条数,如果这 ...
- 「HAOI2018」染色 解题报告
「HAOI2018」染色 是个套路题.. 考虑容斥 则恰好为\(k\)个颜色恰好为\(c\)次的贡献为 \[ \binom{m}{k}\sum_{i\ge k}(-1)^{i-k}\binom{m-k ...
- 「HNOI2016」最小公倍数 解题报告
「HNOI2016」最小公倍数 考虑暴力,对每个询问,处理出\(\le a,\le b\)的与询问点在一起的联通块,然后判断是否是一个联通块,且联通块\(a,b\)最大值是否满足要求. 然后很显然需要 ...
- 「SCOI2016」围棋 解题报告
「SCOI2016」围棋 打CF后困不拉基的,搞了一上午... 考虑直接状压棋子,然后发现会t 考虑我们需要上一行的状态本质上是某个位置为末尾是否可以匹配第一行的串 于是状态可以\(2^m\)压住了, ...
- 「SCOI2016」妖怪 解题报告
「SCOI2016」妖怪 玄妙...盲猜一个结论,然后过了,事后一证,然后假了,数据真水 首先要最小化 \[ \max_{i=1}^n (1+k)x_i+(1+\frac{1}{k})y_i \] \ ...
随机推荐
- DDoS攻击、CC攻击的攻击方式和防御方法
DDoS攻击.CC攻击的攻击方式和防御方法 - sochishun - 博客园https://www.cnblogs.com/sochishun/p/7081739.html cc攻击_百度百科htt ...
- Mysql 5.7 Windows 版本(zip)的安装简单过程
1. 下载zip包 https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.25-winx64.zip 2. 找一个目录解压缩 3. 简单进行安装: ...
- vue-cli3.0之vue.config.js的配置项(注解)
module.exports = { // 部署应用时的基本 URL baseUrl: process.env.NODE_ENV === 'production' ? '192.168.60.110: ...
- rem 自适应、整体缩放
html{ font-size: calc(100vw/7.5); } 说明: 100vw是设备的宽度,除以7.5可以让1rem的大小在iPhone6下等于100px. 若是低版本的设备不支持rem, ...
- python学习笔记(9)--函数
函数定义: def <函数名>(<参数(0个或多个)>): 函数体 return <返回值> 参数有非可选参数,和可选参数,可选参数放在参数列表的最后,可以为可选参 ...
- shiro框架的UsernamePasswordToken与对应Realm中的AuthenticationToken的一点比较
这里以简单的登陆为例子 控制器对应的登陆方法: @RequestMapping(value = "/login", method = RequestMethod.GET) publ ...
- PLSQL 错误问题:Datebase character set (AL32UTF-8) and Client character set (ZHS16GBK) are different.
(解决不了,网上用的是Orecal,我用的只是客户端.) 网上找到解决方法 打开注册表(ctr+R,输入regedit),根据报错提示找到注册表位置,但本机是win10 64位系统,根据以上路径找不到 ...
- Python——Flask框架——模板
一.渲染模板 render_template 函数把Jinja2模板引擎集成到程序中 二.Jinja2变量过滤器 过滤器名 说明 safe 渲染值是不转义 capitalize 把值得首字母转换成大写 ...
- Vue生产环境部署
前面的话 开发时,Vue 会提供很多警告来帮助解决常见的错误与陷阱.生产时,这些警告语句却没有用,反而会增加载荷量.再次,有些警告检查有小的运行时开销,生产环境模式下是可以避免的.本文将详细介绍Vue ...
- caffe boost cuda __float128 undefined
转载:https://blog.csdn.net/thesby/article/details/50512886 编译caffe-master时遇到的问题,__float128未定义,使用到cuda版 ...