zoukankan      html  css  js  c++  java
  • bzoj3571: [Hnoi2014]画框 最小乘积匹配+最小乘积XX总结,

    思路大概同bzoj2395(传送门:http://www.cnblogs.com/DUXT/p/5739864.html),还是将每一种匹配方案的Σai看成x,Σbi看成y,然后将每种方案转化为平面上的点,再用km去找最远的点就行了。

    然而几个月前就学过km且到现在还未写过一道km的题的我并不知道km如何对于负权给出最优解。。。。

    #define XX 某传统算法(例如:最小生成树,二分图最优带权匹配什么的)

    顺便总结一下最小乘积XX

    即对于XX引入两个权值的概念(或是多个权值,一般是两个),看似无从下手,却可以将每一组可行解的方案的两个sum转化为平面内一个点,然后就可以发现一个十分优美的性质即最优解一定在凸包上,于是可以利用一种类似于快包算法的算法,依旧是用XX找出一定在凸包上的两个点,然后再次利用XX进行分治,递归地下去找,弄清楚边界条件(一般一个叉乘就可以轻松搞定),这样问题就被轻易地解决了。(貌似知道了这样的一个模板,基本所有类似问题都可以得到解决)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 #define maxn 100
     8 #define inf 100000000
     9  
    10 int cases,n;
    11 int a[maxn][maxn],b[maxn][maxn],val[maxn][maxn],slack[maxn],valx[maxn],valy[maxn],linky[maxn];
    12 bool visx[maxn],visy[maxn];
    13  
    14 struct point{
    15     int x,y;
    16 }ans;
    17  
    18 point operator -(point a,point b){return(point){a.x-b.x,a.y-b.y};}
    19 double operator *(point a,point b){return a.x*b.y-a.y*b.x;}
    20  
    21 bool find(int x){
    22     visx[x]=1;
    23     for (int y=1;y<=n;y++)
    24         if (!visy[y]){
    25             int t=valx[x]+valy[y]-val[x][y];
    26             if (!t){
    27                 visy[y]=1;
    28                 if (!linky[y]||find(linky[y])){
    29                     linky[y]=x;
    30                     return 1;
    31                 }
    32             }
    33             else slack[y]=min(slack[y],t);
    34         }
    35     return 0;
    36 }
    37  
    38 point km(){
    39     memset(valx,0,sizeof(valx));
    40     memset(valy,0,sizeof(valy));
    41     memset(linky,0,sizeof(linky));
    42     for (int i=1;i<=n;i++)
    43         for (int j=1;j<=n;j++)
    44             valx[i]=max(valx[i],val[i][j]);
    45     for (int x=1;x<=n;x++){
    46         memset(slack,63,sizeof(slack));
    47         while (1){
    48             memset(visx,0,sizeof(visx));
    49             memset(visy,0,sizeof(visy));
    50             if (find(x)) break;
    51             int d=inf;
    52             for (int i=1;i<=n;i++) if (!visy[i]) d=min(d,slack[i]);
    53             for (int i=1;i<=n;i++) if (visx[i]) valx[i]-=d;
    54             for (int i=1;i<=n;i++) if (visy[i]) valy[i]+=d;
    55         }
    56     }
    57     point now={0,0};
    58     for (int i=1;i<=n;i++) now.x+=a[linky[i]][i],now.y+=b[linky[i]][i];
    59     if ((ans.x==inf&&ans.y==inf)||(ans.x*ans.y>now.x*now.y)) ans=now;
    60     return now;
    61 }
    62  
    63 bool operator ==(point a,point b){return a.x==b.x&&a.y==b.y;} 
    64  
    65 void solve(point x,point y){
    66     for (int i=1;i<=n;i++)
    67         for (int j=1;j<=n;j++)
    68             val[i][j]=b[i][j]*(x.x-y.x)+a[i][j]*(y.y-x.y);
    69     point z=km();
    70     if ((z-x)*(y-z)<=0) return;
    71     solve(x,z);
    72     solve(z,y);
    73 }
    74  
    75 int main(){
    76     scanf("%d",&cases);
    77     while (cases--){
    78         scanf("%d",&n);
    79         ans.x=ans.y=inf;
    80         for (int i=1;i<=n;i++)
    81             for (int j=1;j<=n;j++) scanf("%d",&a[i][j]);
    82         for (int i=1;i<=n;i++)
    83             for (int j=1;j<=n;j++) scanf("%d",&b[i][j]);
    84         point minx,miny;
    85         for (int i=1;i<=n;i++) 
    86             for (int j=1;j<=n;j++) val[i][j]=-a[i][j];
    87         minx=km();
    88         for (int i=1;i<=n;i++)
    89             for (int j=1;j<=n;j++) val[i][j]=-b[i][j];
    90         miny=km();
    91         solve(minx,miny);
    92         printf("%d
    ",ans.x*ans.y);
    93     }
    94     return 0;
    95 }
    View Code
  • 相关阅读:
    又玩起了“数独”
    WebService应用:音乐站图片上传
    大家都来DIY自己的Blog啦
    CSS导圆角,不过这个代码没有怎么看懂,与一般的HTML是不同
    网站PR值
    CommunityServer2.0何去何从?
    网络最经典命令行
    炎热八月,小心"落雪"
    Topology activation failed. Each partition must have at least one index component from the previous topology in the new topology, in the same host.
    SharePoint 2013服务器场设计的一些链接
  • 原文地址:https://www.cnblogs.com/DUXT/p/5742995.html
Copyright © 2011-2022 走看看