3571: [Hnoi2014]画框
来源:互联网 发布:淘宝创业好项目 编辑:程序博客网 时间:2024/06/02 18:32
3571: [Hnoi2014]画框
Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 1008 Solved: 572
[Submit][Status][Discuss]
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
Source
[Submit][Status][Discuss]
最小乘积权匹配问题
乘积规划问题有专用套路
换成费用流就解决了
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<algorithm>#include<cmath>#include<stack>#define min(a,b) ((a) < (b) ? (a) : (b))using namespace std;const int N = 155;const int maxm = 2E5 + 20;const int INF = ~0U>>1;struct E{ int to,cap,flow,cost; E(){} E(int to,int cap,int flow,int cost): to(to),cap(cap),flow(flow),cost(cost){}}edgs[maxm];struct Point{ int x,y; Point(){} Point(int x,int y): x(x),y(y){} bool operator < (const Point &B) const {return x * y < B.x * B.y;}}Ans;int n,s,t,T,cnt,X[N][N],Y[N][N],A[N],Cost[N],from[N];bool vis[N];queue <int> Q;vector <int> v[N];inline int getint(){ char ch = getchar(); int ret = 0; while (ch < '0' || '9' < ch) ch = getchar(); while ('0' <= ch && ch <= '9') ret = ret * 10 + ch - '0',ch = getchar(); return ret;}inline void Clear() {for (int i = s; i <= t; i++) v[i].clear(); cnt = 0;}inline void Add(int x,int y,int cap,int Cost){ v[x].push_back(cnt); edgs[cnt++] = E(y,cap,0,Cost); v[y].push_back(cnt); edgs[cnt++] = E(x,0,0,-Cost);}inline void Build(int dx,int dy){ for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) Add(i,j + n,1,X[i][j] * dx + Y[i][j] * dy); Add(s,i,1,0); Add(i + n,t,1,0); }}inline bool SPFA(){ for (int i = s; i <= t; i++) vis[i] = 0,Cost[i] = INF; Q.push(s); vis[s] = 1; Cost[s] = 0; A[s] = INF; while (!Q.empty()) { int k = Q.front(); Q.pop(); vis[k] = 0; for (int i = 0; i < v[k].size(); i++) { E e = edgs[v[k][i]]; if (e.cap == e.flow) continue; if (Cost[e.to] > Cost[k] + e.cost) { from[e.to] = v[k][i]; A[e.to] = min(A[k],e.cap - e.flow); Cost[e.to] = Cost[k] + e.cost; if (!vis[e.to]) vis[e.to] = 1,Q.push(e.to); } } } return Cost[t] != INF;}inline int Cost_Flow(){ int MinCost = 0; while (SPFA()) { MinCost += A[t] * Cost[t]; for (int z = t; z != s; z = edgs[from[z]^1].to) { edgs[from[z]].flow += A[t]; edgs[from[z] ^ 1].flow -= A[t]; } } return MinCost;}inline void Val(Point &C){ C = Point(0,0); for (int i = 1; i <= n; i++) for (int j = 0; j < v[i].size(); j++) { E e = edgs[v[i][j]]; if (e.cap != e.flow) continue; C.x += X[i][e.to - n]; C.y += Y[i][e.to - n]; break; }}inline void Pre_Work(Point &C,int dx,int dy){ Clear(); Build(dx,dy); Cost_Flow(); Val(C);}inline void Calc(Point &C,int dx,int dy,int delta){ Clear(); Build(dx,dy); int ret = Cost_Flow(); if (ret + delta >= 0) {C = Point(-1,-1); return;} Val(C);}inline void Dfs(Point A,Point B){ Point C = Point(-233,-233); int now = A.x * B.y - B.x * A.y; Calc(C,A.y - B.y,B.x - A.x,now); if (C.x == -1 && C.y == -1) return; if (C < Ans) Ans = C; Dfs(A,C); Dfs(C,B);}void Solve(){ n = getint(); s = 0; t = 2 * n + 1; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) X[i][j] = getint(); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) Y[i][j] = getint(); Point A,B; A = B = Point(-233,-233); Pre_Work(A,1,0); Pre_Work(B,0,1); Ans = A; if (B < Ans) Ans = B; Dfs(A,B); cout << Ans.x * Ans.y << endl;}int main(){ #ifdef DMC freopen("DMC.txt","r",stdin); #endif T = getint(); while (T--) Solve(); return 0;}
- 【BZOJ 3571】 [Hnoi2014]画框
- BZOJ 3571: [Hnoi2014]画框
- 3571: [Hnoi2014]画框
- bzoj 3571: [Hnoi2014]画框 最优乘积匹配
- bzoj3571: [Hnoi2014]画框
- BZOJ3571: [Hnoi2014]画框
- BZOJ3571[HNOI2014]画框
- [BZOJ3571][HNOI2014]画框
- bzoj3571: [Hnoi2014]画框
- bzoj3571: [Hnoi2014]画框
- [最小乘积匹配 分治 KM] BZOJ 3571 [Hnoi2014]画框
- 【BZOJ3571】[Hnoi2014]画框【最小乘积匹配】
- 【KM算法】【最大乘积生成树】[HNOI2014] bzoj3571 画框
- BZOJ 3571 画框
- 画框
- BZOJ 3571 [HNOI 2014] 画框 (KM算法+分治)
- BZOJ 3571|HNOI 2014|画框|最优匹配|计算几何
- 画框钉角机
- LINUX中错误 SELinux is disabled
- linux下的git常见操作整理
- (很好的一篇综述) 剖析桌面化 Android 操作系统的发展与未来
- 运行VirtualBox提示0x00000000错误“0x00000000指令引用的0x00000000内存该内存不能为written
- Web前端面试题目及答案汇总
- 3571: [Hnoi2014]画框
- Java回调机制解析
- MaterialDrawer学习心得
- JS刷新页面
- Java设计模式——单例模式(饿汉式、懒汉式)
- SQL删除重复数据只保留一条
- 画图板第二版本
- 选择排序(伪代码算法,c++,以及python实现)
- 链表的几种操作