bzoj3571[Hnoi2014]画框

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;
  }

时间: 2024-12-28 21:11:17

bzoj3571[Hnoi2014]画框的相关文章

bzoj3571: [Hnoi2014]画框 最小乘积匹配+最小乘积XX总结,

思路大概同bzoj2395(传送门:http://www.cnblogs.com/DUXT/p/5739864.html),还是将每一种匹配方案的Σai看成x,Σbi看成y,然后将每种方案转化为平面上的点,再用km去找最远的点就行了. 然而几个月前就学过km且到现在还未写过一道km的题的我并不知道km如何对于负权给出最优解.... #define XX 某传统算法(例如:最小生成树,二分图最优带权匹配什么的) 顺便总结一下最小乘积XX 即对于XX引入两个权值的概念(或是多个权值,一般是两个),看

【BZOJ 3571】 [Hnoi2014]画框

3571: [Hnoi2014]画框 Time Limit: 20 Sec Memory Limit: 128 MB Submit: 513 Solved: 292 [Submit][Status][Discuss] Description 小T准备在家里摆放几幅画,为此他买来了N幅画和N个画框.为了体现他的品味,小T希望能合理地搭配画与画框,使得其显得既不过于平庸也不太违和.对于第 幅画与第 个画框的配对,小T都给出了这个配对的平凡度Aij 与违和度Bij .整个搭配方案的总体不和谐度为每对画

BZOJ 3571 [Hnoi2014]画框(最小乘积完美匹配)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3571 [题目大意] 给出一张二分图,每条边上有a,b两个值,求完美匹配, 使得suma*sumb最小. [题解] 把方案看成一个二维点,x=sum(a),y=sum(b) 答案一定在下凸壳上,找到l,r两个点,l是x最小的,r是y最小的 然后递归调用work(l,r):找到离该直线最远的点,那个点一定在下凸壳上 将边权设为(a,b)叉积(l-r),求出最小完美匹配就是那个点mid 因

树(最小乘积生成树,克鲁斯卡尔算法):BOI timeismoney

The NetLine company wants to offer broadband internet to N towns. For this, it suffices to constructa network of N-1 broadband links between the towns, with the property that a message can travelfrom any town to any other town on this network. NetLin

HNOI2014数据及题解

HNOI2014总结 省选成绩出来了,170分,其中第一天100分,第二天70分,果然和感觉一样,总会有几道题会跪,幸好这才是高一. Day1,一看到第三题就感觉这道题比第一二题好做,但是题目理解错了TAT,一开始竟然脑残到以为这颗树只能是二叉树,于是浪费了一个小时写了一个错误的程序,在检查的时候才发现不一定是二叉树,而且时间只有一个小时了,所以打完50分的算法后就没有去打正解,day1被爆出翔. 第二试,看完题目后觉得只有第一题有点想法,但是由于以前关于字符串的题目都是用pascal写的,所以

bzoj 3572 [Hnoi2014]世界树(虚树+DP)

3572: [Hnoi2014]世界树 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 645  Solved: 362[Submit][Status][Discuss] Description 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生不息.持续运转的根本基石.     世界树的形态可以用一个数学模型来描述:世界树中有n个

BZOJ3575 HNOI2014 道路阻塞

3575: [Hnoi2014]道路堵塞 Time Limit: 10 Sec  Memory Limit: 128 MB Description A国有N座城市,依次标为1到N.同时,在这N座城市间有M条单向道路,每条道路的长度是一个正整数.现在,A国交通部指定了一条从城市1到城市N的路径,并且保证这条路径的长度是所有从城市1到城市N的路径中最短的.不幸的是,因为从城市1到城市N旅行的人越来越多,这条由交通部指定的路径经常发生堵塞.现在A国想知道,这条路径中的任意一条道路无法通行时,由城市1到

【HNOI2014】世界树

P2354 - [HNOI2014]世界树 Description 世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界.在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生不息.持续运转的根本基石. 世界树的形态可以用一个数学模型来描述:世界树中有n个种族,种族的编号分别从1到n,分别生活在编号为1到n的聚居地上,种族的编号与其聚居地的编号相 同.有的聚居地之间有双向的道路相连,道路的长度为1.保证连接的方式会形成一棵树结构,即所有

【BZOJ 3573】 [Hnoi2014]米特运输

3573: [Hnoi2014]米特运输 Time Limit: 20 Sec Memory Limit: 128 MB Submit: 618 Solved: 359 [Submit][Status][Discuss] Description 米特是D星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为主要能源的D星上,这种米特能源的运输和储存一直是一个大问题. D星上有N个城市,我们将其顺序编号为1到N,1号城市为首都.这N个城市由N-1条单向高速通道连接起来,构成一棵以1号城市(首部)为