[BZOJ3571][HNOI2014]画框
来源:互联网 发布:久其软件 决算 编辑:程序博客网 时间:2024/06/11 05:58
我反正是绝对做不出来。
我们把每个决策的
怎么求C?
后两项为定值,只需前两项最大即可。
那么令二分图的权值
这一题的复杂度好像并不明确。。。
这里再说一下KM算法的优化,sla要在外层循环清INF,每次DFS不是相等子图中的边则需要更新,然后update记得减去。因为sla是Y’中的点与X中的点的
#include<ctime>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<iostream>#include<string>#include<cassert>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<sstream>#include<climits>#define X first#define Y second#define DB double#define lc now<<1#define rc now<<1|1#define MP make_pair#define LL long long#define pb push_back#define sqr(_) ((_)*(_))#define INF 0x3f3f3f3f#define pii pair<int,int>#define pdd pair<DB,DB>#define ull unsigned LL#define DEBUG(...) fprintf(stderr,__VA_ARGS__)using namespace std;template<typename T>void Read(T& x){ x=0;int flag=0,sgn=1;char c; while(c=getchar()) { if(c=='-')sgn=-1; else if(c>='0'&&c<='9')x*=10,x+=c-'0',flag=1; else if(flag)break; } x*=sgn;}const int MAXN=80;int T,n,A[MAXN][MAXN],B[MAXN][MAXN],G[MAXN][MAXN];struct KM{ bool S[MAXN],T[MAXN]; int lx[MAXN],ly[MAXN],sla[MAXN],left[MAXN]; bool match(int i) { S[i]=1; for(int j=1;j<=n;j++) if(!T[j]) { if(lx[i]+ly[j]==G[i][j]) { T[j]=1; if(!left[j]||match(left[j])){ left[j]=i; return 1; } } else sla[j]=min(sla[j],lx[i]+ly[j]-G[i][j]); } return 0; } void update() { int d=INF; for(int i=1;i<=n;i++)if(!T[i]) d=min(d,sla[i]); for(int i=1;i<=n;i++) { if(S[i])lx[i]-=d; if(T[i])ly[i]+=d; else sla[i]-=d; } } pii km() { pii res=MP(0,0); memset(left,0,sizeof(left)); memset(ly,0,sizeof(ly)); memset(lx,0,sizeof(lx)); 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,INF,sizeof(sla)); while(1) { memset(S,0,sizeof(S)); memset(T,0,sizeof(T)); if(match(i))break; else update(); } } for(int i=1;i<=n;i++) { res.X+=A[left[i]][i]; res.Y+=B[left[i]][i]; } return res; }}Graph;void init(){ Read(n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) Read(A[i][j]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) Read(B[i][j]);}void build(pii& l,pii& r){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) G[i][j]=(r.Y-l.Y)*A[i][j]+(l.X-r.X)*B[i][j];}int work(pii l,pii r){ build(l,r); pii mid=Graph.km(); if(l==mid||r==mid)return min(l.X*l.Y,r.X*r.Y); return min(work(l,mid),work(mid,r));}void solve(){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) G[i][j]=-A[i][j]; pii st=Graph.km(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) G[i][j]=-B[i][j]; pii ed=Graph.km(); cout<<work(st,ed)<<endl;}int main(){#ifndef ONLINE_JUDGE freopen("frame.in","r",stdin); freopen("frame.out","w",stdout);#endif Read(T); while(T--) { init(); solve(); }}
0 0
- bzoj3571: [Hnoi2014]画框
- BZOJ3571: [Hnoi2014]画框
- BZOJ3571[HNOI2014]画框
- [BZOJ3571][HNOI2014]画框
- bzoj3571: [Hnoi2014]画框
- bzoj3571: [Hnoi2014]画框
- 【BZOJ3571】[Hnoi2014]画框【最小乘积匹配】
- 【KM算法】【最大乘积生成树】[HNOI2014] bzoj3571 画框
- 【BZOJ 3571】 [Hnoi2014]画框
- BZOJ 3571: [Hnoi2014]画框
- 3571: [Hnoi2014]画框
- bzoj 3571: [Hnoi2014]画框 最优乘积匹配
- bzoj3571
- [最小乘积匹配 分治 KM] BZOJ 3571 [Hnoi2014]画框
- 画框
- 画框钉角机
- 【HNOI2014】Jabberwocky
- BZOJ3571【最小乘积最大匹配】
- Unity学习笔记——利用脚本实现对一个物体的第三人称观察
- Unity基于NGUI实现拖拽功能
- 8. Smarty 基本语法
- Android 5.0之后 点击 悬浮穿回到顶部。
- Android中SQLite的使用
- [BZOJ3571][HNOI2014]画框
- POJ 2828 Buy Tickets(线段树—查找并更新从左到右的第i个1)
- fms服务端语法
- Android Hanlder综合
- XZ_iOS中推送通知~本地推送通知的实现
- 太阳理论
- 上下界网络流
- Codeforces 633D Fibonacci-ish(暴力)
- 为什么子线程不能更新Toas