题目链接

BZOJ3571

题解

如果知道最小乘积生成树,那么这种双权值乘积最小就是裸题了

将两权值和作为坐标,转化为二维坐标系下凸包上的点,然后不断划分分治就好了

这里求的是最小匹配值,每次找点套一个二分图最小权匹配

为什么用KM算法?因为这道题丧心病狂卡费用流QAQ

写完就A啦,十分的感人

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 75,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int n,X[maxn][maxn],Y[maxn][maxn];
int w[maxn][maxn],expa[maxn],expb[maxn],cp[maxn],visa[maxn],visb[maxn],dl[maxn];
struct point{int x,y;}ans;
inline point operator -(const point& a,const point& b){
return (point){a.x - b.x,a.y - b.y};
}
inline LL operator *(const point& a,const point& b){
return 1ll * a.x * b.y - 1ll * a.y * b.x;
}
inline bool operator <(const point& a,const point& b){
return 1ll * a.x * a.y == 1ll * b.x * b.y ? a.x < b.x : 1ll * a.x * a.y < 1ll * b.x * b.y;
}
bool dfs(int u){
visa[u] = true;
REP(i,n) if (!visb[i]){
int kl = expa[u] + expb[i] - w[u][i];
if (!kl){
visb[i] = true;
if (!cp[i] || dfs(cp[i])) {cp[i] = u; return true;}
}
else dl[i] = min(dl[i],kl);
}
return false;
}
point km(){
REP(i,n) expa[i] = -INF,expb[i] = cp[i] = 0;
REP(i,n) REP(j,n) expa[i] = max(expa[i],w[i][j]);
REP(i,n){
REP(j,n) dl[j] = INF;
while (true){
REP(j,n) visa[j] = visb[j] = false;
if (dfs(i)) break;
int kl = INF;
REP(j,n) if (!visb[j]) kl = min(kl,dl[j]);
REP(j,n){
if (visa[j]) expa[j] -= kl;
if (visb[j]) expb[j] += kl;
else dl[j] -= kl;
}
}
}
point re; re.x = re.y = 0;
REP(i,n) re.x += X[cp[i]][i],re.y += Y[cp[i]][i];
if (re < ans) ans = re;
return re;
}
void solve(point A,point B){
REP(i,n) REP(j,n) w[i][j] = -((A.y - B.y) * X[i][j] + (B.x - A.x) * Y[i][j]);
point C = km();
if ((C - A) * (B - A) <= 0) return;
solve(A,C); solve(C,B);
}
int main(){
int T = read();
while (T--){
n = read(); ans.x = INF; ans.y = INF;
REP(i,n) REP(j,n) X[i][j] = read();
REP(i,n) REP(j,n) Y[i][j] = read();
REP(i,n) REP(j,n) w[i][j] = -X[i][j];
point A = km();
REP(i,n) REP(j,n) w[i][j] = -Y[i][j];
point B = km();
solve(A,B);
printf("%d\n",ans.x * ans.y);
}
return 0;
}

BZOJ3571 [Hnoi2014]画框 【分治 + KM算法】的更多相关文章

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

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

  2. BZOJ3571 : [Hnoi2014]画框

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

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

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

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

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

  5. 【LG3236】[HNOI2014]画框

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

  6. 匈牙利算法与KM算法

    匈牙利算法 var i,j,k,l,n,m,v,mm,ans:longint; a:..,..]of longint; p,f:..]of longint; function xyl(x,y:long ...

  7. 【HDU2255】奔小康赚大钱-KM算法

    Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description ...

  8. HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法

    二分图最大权值匹配问题.用KM算法. 最小权值的时候把权值设置成相反数 /*-------------------------------------------------------------- ...

  9. KM算法及其优化的学习笔记&&bzoj2539: [Ctsc2000]丘比特的烦恼

    感谢  http://www.cnblogs.com/vongang/archive/2012/04/28/2475731.html 这篇blog里提供了3个链接……基本上很明白地把KM算法是啥讲清楚 ...

随机推荐

  1. 网络编程——UDP协议和通信

    第1章 UDP与TCP协议 在介绍TCP/IP结构时,提到传输层的两个重要的高级协议,分别是UDP和TCP,其中UDP是User Datagram Protocol的简称,称为用户数据报协议,TCP是 ...

  2. ES6 Proxy拦截器详解

    Proxy 拦截器 如有错误,麻烦指正,共同学习 Proxy的原意是"拦截",可以理解为对目标对象的访问和操作之前进行一次拦截.提供了这种机制,所以可以对目标对象进行修改和过滤的操 ...

  3. A1043 Is It a Binary Search Tree (25 分)

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  4. MitmProxy使用

    安装 tar -zxvf mitmproxy-3.0.1-linux.tar.gz sudo mv mitmproxy mitmdump mitmweb /usr/bin 详情 https://ger ...

  5. GNU汇编程序框架

    汇编的作用:1.对芯片进行初始化 2. 和C混合编程提升C的运行效率 .section .data < 初始化的数据> .section .bss <未初始化的数据> .sec ...

  6. MySQL 时间戳与日期互相转换

    MySQL 时间戳与日期互相转换 1.时间戳转换成日期 函数:FROM_UNIXTIME() ,'%Y年%m月%d日') 结果为:2015年04月15日 2.把日期转换为时间戳,和 FROM_UNIX ...

  7. ICSharpCode.SharpZipLib.dll

    using ICSharpCode.SharpZipLib.Checksums; using ICSharpCode.SharpZipLib.Zip; namespace { /// <summ ...

  8. P2920 [USACO08NOV]时间管理Time Management

    P2920 [USACO08NOV]时间管理Time Management 题目描述 Ever the maturing businessman, Farmer John realizes that ...

  9. seajs引入jquery

    seajs 2.2.1在config文件中preload一次jquery,就可以在整个项目中使用jquery.如下: seajs.on('exec', function(module) { if (m ...

  10. RSA进阶之低加密指数攻击

    适用场景: n很大,4000多位,e很小,e=3 一般来说,e选取65537.但是在RSA加密的时候有可能会选用e=3(不要问为什么,因为选取e =3省时省力,并且他可能觉得n在4000多位是很安全的 ...