博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ3571: [Hnoi2014]画框
阅读量:5122 次
发布时间:2019-06-13

本文共 3729 字,大约阅读时间需要 12 分钟。

Description

小T准备在家里摆放几幅画,为此他买来了N幅画和N个画框。为了体现他的品味,小T希望能合理地搭配画与画框,使得其显得既不过于平庸也不太违和。对于第 幅画与第 个画框的配对,小T都给出了这个配对的平凡度Aij 与违和度Bij 。整个搭配方案的总体不和谐度为每对画与画框平凡度之和与每对画与画框违和度的乘积。具体来说,设搭配方案中第i幅画与第Pi个画框配对,则总体不和谐度为

小T希望知道通过搭配能得到的最小的总体不和谐度是多少。

Input

输入文件第 行是一个正整数T ,表示数据组数,接下来是T组数据。

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

Output

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

Sample Input

1
3
4 3 2
2 3 4
3 2 1
2 3 2
2 2 4
1 1 3

Sample Output

30

HINT

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

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


题解Here!

 

这题目难道掉牙了。。。
我们会发现这个很像最小乘积生成树。
于是我们把一种匹配的$\sum A_i$和$\sum B_i$分别看作横纵坐标,然后找$x \times y$最小的点。
可以先找出$x$最小的点$A$和$y$最小的点$B$,然后找$AB$左下方离$AB$最远的点$C$。
即$\overrightarrow{AB}\times\overrightarrow{AC}$最小。
然后把$\overrightarrow{AB}\times\overrightarrow{AC}$拆开:
$$\left.\begin{array}{}\overrightarrow{AB}\times\overrightarrow{AC}&=&(x_B-x_A)\times(y_C-y_A)-(y_B-y_A)\times(x_C-x_A) \\&=&(x_B-x_A)\times y_C+(y_A-y_B)\times x_C+y_B\times x_A-x_B\times y_A\end{array}\right.$$    

在程序中我的$A,B,C$用$one,two,three$代替了,注意一下。。。

那么把权值改成$map[i][j]=(y_A-y_B)\times A[i][j]+(x_B-x_A)\times B[i][j]$,再用带权二分图匹配就可以找出$C$。
带权二分图匹配这个丢给了$KM$,当然费用流也是可行的,不过我比较懒就不写了。。。
找出$C$后用叉积判断$C$是不是在$AB$的下方,如果是,就递归解决线段$AC$和$CB$。
然后就做完了。。。
没想到头一次写$KM$还是在这道题,我连板子题还没写呢。。。
没学会走,先学会飞了。。。
附代码:
#include
#include
#include
#include
#define MAXN 80#define MAX 999999999using namespace std;int n,ans;int A[MAXN][MAXN],B[MAXN][MAXN];struct Vector{ int x,y; friend Vector operator +(const Vector p,const Vector q){return (Vector){p.x+q.x,p.y+q.x};} friend Vector operator -(const Vector p,const Vector q){return (Vector){p.x-q.x,p.y-q.y};} friend int operator *(const Vector p,const Vector q){return p.x*q.y-p.y*q.x;}};inline int read(){ int date=0,w=1;char c=0; while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();} while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();} return date*w;}namespace G{ int f[MAXN],valx[MAXN],valy[MAXN],val[MAXN],map[MAXN][MAXN]; bool visx[MAXN],visy[MAXN]; inline void buildgraph(int x,int y){ for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)map[i][j]=-(x*A[i][j]+y*B[i][j]); } bool find(int x){ visx[x]=true; for(int i=1;i<=n;i++){ if(visy[i])continue; int t=valx[x]+valy[i]-map[x][i]; if(!t){ visy[i]=true; if(f[i]==-1||find(f[i])){ f[i]=x; return true; } } else val[i]=min(val[i],t); } return false; } Vector KM(){ Vector s=(Vector){0,0}; memset(f,-1,sizeof(f)); memset(valx,0,sizeof(valx)); memset(valy,0,sizeof(valy)); for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)valx[i]=max(valx[i],map[i][j]); for(int i=1;i<=n;i++){ memset(val,63,sizeof(val)); while(1){ memset(visx,false,sizeof(visx)); memset(visy,false,sizeof(visy)); if(find(i))break; int w=MAX; for(int i=1;i<=n;i++)if(!visy[i])w=min(w,val[i]); for(int i=1;i<=n;i++)if(visx[i])valx[i]-=w; for(int i=1;i<=n;i++){ if(visy[i])valy[i]+=w; else val[i]-=w; } } } for(int i=1;i<=n;i++){ s.x+=A[f[i]][i]; s.y+=B[f[i]][i]; } return s; }}void solve(Vector one,Vector two){ G::buildgraph(one.y-two.y,two.x-one.x); Vector three=G::KM(); ans=min(ans,three.x*three.y); if(((two-one)*(three-one))>=0)return; solve(one,three);solve(three,two);}void work(){ Vector one,two; G::buildgraph(1,0); one=G::KM(); G::buildgraph(0,1); two=G::KM(); ans=min(one.x*one.y,two.x*two.y); solve(one,two); printf("%d\n",ans);}void init(){ n=read(); for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)A[i][j]=read(); for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)B[i][j]=read();}int main(){ int t=read(); while(t--){ init(); work(); } return 0;}

 

转载于:https://www.cnblogs.com/Yangrui-Blog/p/9693025.html

你可能感兴趣的文章
HDU 5429 Geometric Progression
查看>>
mysql 视图入门
查看>>
[原创]Eclipse Memory Analyzer tool(MAT)工个使用介绍
查看>>
CFileDialog(文件夹对话框类)和CFontDialog(字体设置对话框类)的使用学习
查看>>
ENGGEN 131 – Summer School
查看>>
js基于Layui模块化封装
查看>>
maven plugins
查看>>
解决sublime text3 中文字符乱码
查看>>
paramiko之ssh用法
查看>>
restframework
查看>>
每日英语:Hard Math: Adding Up Just How Little We Actually Move
查看>>
安装 tomacat出现问题总结
查看>>
系统数据库--修改tempdb的位置
查看>>
曲演杂坛--Update的小测试
查看>>
[Cocos2D-x For WP8]Sprite精灵
查看>>
事务日志管理--不断增长的日志文件
查看>>
(转)MATLAB入门教程
查看>>
shell脚本报错:"[: =: unary operator expected"
查看>>
yii 正则验证
查看>>
HDU1754-ZKW线段树
查看>>