题目描述

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

对于第 幅画与第 个画框的配对,小T都给出了这个配对的平凡度Aij 与违和度Bij 。整个搭配方案的总体不和谐度为每对画与画框平凡度之和与每对画与画框违和度的乘积。具体来说,设搭配方案中第i幅画与第Pi个画框配对,则总体不和谐度为 小T希望知道通过搭配能得到的最小的总体不和谐度是多少。

输入输出格式

输入格式:

输入文件第 行是一个正整数T ,表示数据组数,接下来是T组数据。对于每组数据,第
行是一个正整数N,表示有N对画和画框。第2到第N+1行,每行有N个非负整数,第i+1 行第j个数表示Aij
。第N+2到第2*N+1行,每行有N个非负整数,第i+N+1 行第j个数表示Bij 。

输出格式:

包含T!行,每行一个整数,表示最小的总体不和谐度

输入输出样例

输入样例#1:
复制

1
3
4 3 2
2 3 4
3 2 1
2 3 2
2 2 4
1 1 3
输出样例#1: 复制

30

说明

第1幅画搭配第3个画框,第2幅画搭配第1个画框,第3 幅画搭配第2个画框,则总体不和谐度为30

N<=70,T<=3,Aij<=200,Bij<=200

学了最小乘积生成树后发现这题很相似

只不过把生成树换成了KM

还有这题求的是最小值,而KM求的是最大匹配
所以权要取负,算出来的点也取负

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long lol;
struct Node
{
lol x,y;
};
Node operator -(Node u,Node v)
{
return (Node){u.x-v.x,u.y-v.y};
}
Node operator +(Node u,Node v)
{
return (Node){u.x+v.x,u.y+v.y};
}
lol operator *(Node u,Node v)
{
return u.x*v.y-u.y*v.x;
}
lol a[][],b[][],c[][];
bool vis1[],vis2[];
lol E1[],E2[],n,match[],slack[];
lol ans;
bool dfs(int x)
{int i,j;
vis1[x]=;
for (i=;i<=n;i++)
if (vis2[i]==)
{
lol gap=E1[x]+E2[i]-c[x][i];
if (gap==)
{
vis2[i]=;
if (match[i]==-||dfs(match[i]))
{
match[i]=x;
return ;
}
}
else slack[i]=min(slack[i],gap);
}
return ;
}
Node KM()
{int i,j;
lol tmp;
memset(match,-,sizeof(match));
for (i=;i<=n;i++)
{
E2[i]=;
tmp=;
for (j=;j<=n;j++)
{
if (c[i][j]>tmp) tmp=c[i][j];
}
E1[i]=tmp;
}
for (i=;i<=n;i++)
{
for (j=;j<=n;j++)
slack[j]=1e15;
while ()
{
memset(vis1,,sizeof(vis1));
memset(vis2,,sizeof(vis2));
if (dfs(i)) break;
lol tmp=1e15;
for (j=;j<=n;j++)
if (vis2[j]==&&tmp>slack[j]) tmp=slack[j];
for (j=;j<=n;j++)
{
if (vis1[j]) E1[j]-=tmp;
if (vis2[j]) E2[j]+=tmp;
else slack[j]-=tmp;
}
}
}
lol ansa=,ansb=;
for (i=;i<=n;i++)
ansa+=a[match[i]][i],ansb+=b[match[i]][i];
return (Node){-ansa,-ansb};
}
lol cross(Node p,Node A,Node B)
{
return (A-p)*(B-p);
}
void solve(Node B,Node A)
{int i,j;
Node C;
lol x=(A.y-B.y),y=(B.x-A.x);
for (i=;i<=n;i++)
for (j=;j<=n;j++)
c[i][j]=-a[i][j]*x-b[i][j]*y;
C=KM();
if (C.x*C.y<ans) ans=C.x*C.y;
if (cross(C,B,A)>=) return;
solve(B,C);
solve(C,A);
}
int main()
{Node A,B;
int i,j,T;
cin>>T;
while (T--)
{
cin>>n;
ans=2e9;
for (i=;i<=n;i++)
for (j=;j<=n;j++)
scanf("%lld",&a[i][j]);
for (i=;i<=n;i++)
for (j=;j<=n;j++)
scanf("%lld",&b[i][j]);
for (i=;i<=n;i++)
for (j=;j<=n;j++)
c[i][j]=-b[i][j];
A=KM();
if (A.x*A.y<ans) ans=A.x*A.y;
for (i=;i<=n;i++)
for (j=;j<=n;j++)
c[i][j]=-a[i][j];
B=KM();
if (B.x*B.y<ans) ans=B.x*B.y;
solve(B,A);
printf("%lld\n",ans);
}
}

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

  1. 【LG3236】[HNOI2014]画框

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

  2. bzoj 3571: [Hnoi2014]画框

    Description 小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. jquery empty()方法在IE下报错的解决办法

    empty()在IE中没反应的办法: 用原生的js解决: try { $("#id" ).empty(); } catch (e) { $("#id")[0]. ...

  2. alpha-咸鱼冲刺day6

    一,合照 emmmmm.自然还是没有的. 二,项目燃尽图 三,项目进展 !!!QAQ可以做到跟数据库交互了!!!!先来撒花花!(然后继续甲板) (然后就没有进展了.翻车+1s) 四,问题困难 数据库交 ...

  3. 201621123050 《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 答:接口.has-a.comparable 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需要出现过多的字. ...

  4. 关于使用栈将一般运算式翻译为后缀表达式并实现三级运算的方法及实例(cpp版)

    #include <iostream> #include <stack> #include <vector> #include <string> #de ...

  5. VisualVM 使用 service:jmx:rmi:///...无法连接linux远程服务器

    VisualVM 无法使用 service:jmx:rmi:///jndi/rmi:///jmxrmi 连接到 关闭远程机器的防火墙即可:service iptables stop 不关闭防火墙的解决 ...

  6. JAVA_SE基础——15.循环嵌套

    嵌套循环是指在一个循环语句的循环体中再定义一个循环语句结构,while,do-while,for循环语句都可以进行嵌套,并且可以互相嵌套,下面来看下for循环中嵌套for循环的例子. 如下: publ ...

  7. 【转】支持向量机(SVM)

    什么是支持向量机(SVM)? SVM 是一种有监督的机器学习算法,可用于分类或回归问题.它使用一种称为核函数(kernel)的技术来变换数据,然后基于这种变换,算法找到预测可能的两种分类之间的最佳边界 ...

  8. Mego开发文档 - 基本保存操作

    基本保存操作 在Mego中没有更改跟踪,也就是说所有的新增.更新及删除都需要开发者自行判断.Mego会最为实际的将各个数据操作提交给数据库并执行. 添加数据 using (var db = new O ...

  9. 新概念英语(1-141)Sally's first train ride

    Lesson 141 Sally's first train ride 萨莉第一交乘火车旅行 Listen to the tape then answer this question. Why was ...

  10. ELK学习总结(2-4)bulk 批量操作-实现多个文档的创建、索引、更新和删除

    bulk 批量操作-实现多个文档的创建.索引.更新和删除 ----------------------------------------------------------------------- ...