【LG3236】[HNOI2014]画框

题面

洛谷

题解

这题一模一样。

将最小生成树换成\(KM\)即可。

关于复杂度,因为决策点肯定在凸包上,且\(n\)凸包的期望点数为\(\sqrt {\ln n}\)

所以\(n!\)个点的期望点数为\(\sqrt {\ln n!}=\sqrt {\sum_{i=1}^ni}\)

所以总复杂度\(O(\sqrt {\ln n!}*n^4)\)

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int INF = 1e9;
const int MAX_N = 100;
struct Point { int x, y; } ;
Point operator - (const Point &l, const Point &r) { return (Point){l.x - r.x, l.y - r.y}; }
int cross(const Point &l, const Point &r) { return l.x * r.y - l.y * r.x; }
int N, ans;
namespace Gra {
int A[MAX_N][MAX_N], B[MAX_N][MAX_N];
int g[MAX_N][MAX_N], lx[MAX_N], ly[MAX_N], sla[MAX_N], match[MAX_N];
bool visx[MAX_N], visy[MAX_N];
void build(int wx, int wy) {
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
g[i][j] = -(wx * A[i][j] + wy * B[i][j]);
}
bool dfs(int u) {
visx[u] = true;
for (int v = 1; v <= N; v++)
if (!visy[v]) {
int t = lx[u] + ly[v] - g[u][v];
if (!t) {
visy[v] = 1;
if (!match[v] || dfs(match[v])) {
match[v] = u;
return true;
}
}
else sla[v] = min(sla[v], t);
}
return false;
}
Point KM() {
memset(lx, 0, sizeof(lx));
memset(ly, 0, sizeof(ly));
memset(match, 0, sizeof(match));
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
lx[i] = max(lx[i], g[i][j]);
for (int i = 1; i <= N; i++) {
memset(sla, 63, sizeof sla);
while (1) {
memset(visx, 0, sizeof visx);
memset(visy, 0, sizeof visy);
if (dfs(i)) break;
int d = INF;
for (int i = 1; i <= N; i++)
if (!visy[i]) d = min(d, sla[i]);
for (int i = 1; i <= N; i++)
if (visx[i]) lx[i] -= d;
for (int i = 1; i <= N; i++)
if (visy[i]) ly[i] += d;
else sla[i] -= d;
}
}
Point res = (Point){0, 0};
for (int i = 1; i <= N; i++)
res.x += A[match[i]][i], res.y += B[match[i]][i];
return res;
}
}
void Div(Point A, Point B) {
Gra::build(A.y - B.y, B.x - A.x);
Point C = Gra::KM();
ans = min(ans, C.x * C.y);
if (cross(B - A, C - A) >= 0) return ;
Div(A, C), Div(C, B);
}
int main () {
#ifndef ONLINE_JUDGE
freopen("cpp.in", "r", stdin);
#endif
int T; scanf("%d", &T);
while (T--) {
scanf("%d", &N);
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
scanf("%d", &Gra::A[i][j]);
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
scanf("%d", &Gra::B[i][j]);
Gra::build(1, 0);
Point A = Gra::KM();
Gra::build(0, 1);
Point B = Gra::KM();
ans = min(A.x * A.y, B.x * B.y);
Div(A, B);
printf("%d\n", ans);
}
return 0;
}

【LG3236】[HNOI2014]画框的更多相关文章

  1. bzoj 3571: [Hnoi2014]画框

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

  2. [HNOI2014]画框

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

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

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

  4. BZOJ3571 : [Hnoi2014]画框

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

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

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

  6. luogu P3236 [HNOI2014]画框

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

  7. 【bzoj3751】 Hnoi2014—画框

    http://www.lydsy.com/JudgeOnline/problem.php?id=3571 (题目链接) 题意 给出一个$2*N$个点的二分图,$N*N$条边,连接$i$和$j$的边有两 ...

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

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

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

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

随机推荐

  1. PhoneGap API 之事件处理_双击返回键退出程序

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  2. Linux环境编程之IPC进程间通信(五):Posix消息队列1

    对于管道和FIFO来说.必须应该先有读取者存在.否则先有写入者是没有意义的. 而消息队列则不同,它是一个消息链表,有足够写权限的线程可往别的队列中放置消息,有足够读权限的线程可从队列中取走消息.每一个 ...

  3. 【[APIO2007]动物园】

    我好\(sb\)啊,把\(>>\)打成\(<<\)结果就写了两节课 那个一个人只能看到五个动物显然很鬼畜 那我们就可以压这一维了 \(dp[i][s]\)表示从第\(i\)个位 ...

  4. E、CSL 的魔法 【模拟】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛)

    题目传送门:https://ac.nowcoder.com/acm/contest/551#question 题目描述 有两个长度为 n 的序列,a0,a1,…,an−1a0,a1,…,an−1和 b ...

  5. 淡说Linux 的发展史

    ♦ 1  Linux的简单介绍 Linux与Windows一样都是一套OS(操作系统),Windows界面美观 ,普通用户很容易上手,点点鼠标就能搞定许多操作,而Linux生下来就是为程序员的,故精通 ...

  6. SpringBoot实战(五)之Thymeleaf

    Thymeleaf同jsp.volocity.freemarker等共同的职能是MVC模式中的视图展示层,即View. 当然了,SpringBoot中也可以用jsp,不过不推荐这种用法,比较推崇的就是 ...

  7. Qt中QScrollArea类的简单使用心得

           平台:windows 64位        Qt版本:5.5.1 MinGW 32bit 根据自己目前的需求简单说下怎么在QScrollArea滚动窗口中实现多个控件的滚动显示,先看看最 ...

  8. Linux中PATH环境变量的作用和使用方法

    关于PATH的作用:PATH说简单点就是一个字符串变量,当输入命令的时候LINUX会去查找PATH里面记录的路径.比如在根目录/下可以输入命令ls,在/usr目录下也可以输入ls,但其实ls这个命令根 ...

  9. springmvc整合mybatis框架源码 bootstrap html5 mysql oracle maven SSM

    A 调用摄像头拍照,自定义裁剪编辑头像 [新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统]B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,开发利器)+快速构建表单;  技 ...

  10. 832. Flipping an Image (5月22日 )

    解答 class Solution { public: vector<vector<int>> flipAndInvertImage(vector<vector<i ...