您的位置:首页 > 其它

bzoj3571[Hnoi2014]画框

2016-02-25 22:13 295 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=3571

好吧,裸的最小乘积匹配

现在才会KM算法。。。。。。。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<set>
#include<bitset>
#include<vector>
#include<functional>
#include<deque>
#include<cctype>
#include<climits>
#include<complex>
#include<cassert>
//#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj

using namespace std;

typedef long long LL;
typedef double DB;
typedef pair<int,int> PII;
typedef pair<DB,DB> PDD;
typedef complex<DB> CP;
typedef vector<int> VI;

#define mmst(a,v) memset(a,v,sizeof(a))
#define mmcy(a,b) memcpy(a,b,sizeof(a))
#define fill(a,l,r,v) fill(a+l,a+r+1,v)
#define re(i,a,b)  for(i=(a);i<=(b);i++)
#define red(i,a,b) for(i=(a);i>=(b);i--)
#define fi first
#define se second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define SF scanf
#define PF printf
#define two(k) (1<<(k))
#define SZ(x) (int(x.size()))
#define all(x) (x).begin(),(x).end()
#define ire(i,v,x) for(i=0,v=i<SZ(x)?x[i]:0;i<SZ(x);v=x[++i])

template<class T>inline T sqr(T x){return x*x;}
template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}

inline int sgn(DB x){if(abs(x)<1e-9)return 0;return(x>0)?1:-1;}
const DB Pi=acos(-1.0);

int gint()
{
int res=0;bool neg=0;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return 0;
if(z=='-'){neg=1;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
return (neg)?-res:res;
}
LL gll()
{
LL res=0;bool neg=0;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return 0;
if(z=='-'){neg=1;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
return (neg)?-res:res;
}

const int maxn=75;
const int inf=0x3f3f3f3f;

int n;
int A[maxn][maxn],B[maxn][maxn];
int ans;

int val[maxn][maxn];
int lx[maxn],ly[maxn],p[maxn],from[maxn],slk[maxn];
int ci,visx[maxn],visy[maxn];
int dfs(int i)
{
int j;
visx[i]=ci;
re(j,1,n)
if(lx[i]+ly[j]>val[i][j])
upmin(slk[j],lx[i]+ly[j]-val[i][j]);
else if(visy[j]!=ci)
{
visy[j]=ci;
if(!from[j] || dfs(from[j])){from[j]=i;return 1;}
}
return 0;
}
void KM()
{
int i,j,cost;
re(i,1,n)re(j,1,n)val[i][j]=-val[i][j];
re(i,1,n)
{
lx[i]=-inf;ly[i]=0;from[i]=0;
re(j,1,n)upmax(lx[i],val[i][j]);
}
re(i,1,n)
{
re(j,1,n)slk[j]=inf;
ci++;
while(!dfs(i))
{
int d=inf;
re(j,1,n)if(visy[j]!=ci)upmin(d,slk[j]);
re(j,1,n)if(visx[j]==ci)lx[j]-=d;
re(j,1,n)if(visy[j]==ci)ly[j]+=d;
re(j,1,n)slk[j]=inf;
ci++;
}
}
re(i,1,n)p[from[i]]=i;
re(i,1,n)re(j,1,n)val[i][j]=-val[i][j];
}

void solve(int x1,int y1,int x2,int y2)
{
int i,j,res=x1*y2-x2*y1,x=0,y=0;
re(i,1,n)re(j,1,n)val[i][j]=(y1-y2)*A[i][j]+(x2-x1)*B[i][j];
KM();
re(i,1,n)res+=val[i][p[i]],x+=A[i][p[i]],y+=B[i][p[i]];
if(res>=0)return;
upmin(ans,x*y);
solve(x1,y1,x,y);
solve(x,y,x2,y2);
}

int main()
{
freopen("frame.in","r",stdin);
freopen("frame.out","w",stdout);
int i,j,T=gint();
while(T--)
{
n=gint();
re(i,1,n)re(j,1,n)A[i][j]=gint();
re(i,1,n)re(j,1,n)B[i][j]=gint();
int x1=0,y1=0,x2=0,y2=0;
mmcy(val,A);
KM();
re(i,1,n)x1+=A[i][p[i]],y1+=B[i][p[i]];
mmcy(val,B);
KM();
re(i,1,n)x2+=A[i][p[i]],y2+=B[i][p[i]];
ans=min(x1*y1,x2*y2);
solve(x1,y1,x2,y2);
cout<<ans<<endl;
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: