• BZOJ 3571 画框


    这一类的问题都可以这样分治来做。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 150
    #define inf 2000000000
    using namespace std;
    int t,n,a[maxn][maxn],b[maxn][maxn];
    int lx[maxn],ly[maxn],slack[maxn],linky[maxn],w[maxn][maxn];
    bool visx[maxn],visy[maxn];
    struct point
    {
        int a,b;
        point (int a,int b):a(a),b(b) {}
        point () {}
        friend bool operator < (const point & x,const point & y)
        {
            return (long long)x.a*x.b<(long long)y.a*y.b;
        }
        friend point operator - (const point & x,const point & y)
        {
            return point(x.a-y.a,x.b-y.b);
        }
        friend int operator * (const point & x,const point & y)
        {
            return x.a*y.b-x.b*y.a;
        }
    }ans;
    bool hungary(int x)
    {
        visx[x]=true;
        for (int i=1;i<=n;i++)
        {
            if (visy[i]) continue;
            int t=-lx[x]-ly[i]+w[x][i];
            if (!t)
            {
                visy[i]=true;
                if (linky[i]==-1 || (hungary(linky[i])))
                {
                    linky[i]=x;
                    return true;
                }
            }
            else slack[i]=min(slack[i],t);
        }
        return false;
    }
    point KM()
    {
        for (int i=1;i<=n;i++) linky[i]=-1,lx[i]=inf,ly[i]=0;
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
                lx[i]=min(lx[i],w[i][j]);
        for (int i=1;i<=n;i++)
        {
            for (int j=1;j<=n;j++) slack[j]=inf;
            for (;;)
            {
                memset(visx,false,sizeof(visx));
                memset(visy,false,sizeof(visy));
                if (hungary(i)) break;
                int d=inf;
                for (int j=1;j<=n;j++)
                    if (!visy[j]) d=min(d,slack[j]);
                for (int j=1;j<=n;j++)
                {
                    if (visx[j]) lx[j]+=d;
                    if (visy[j]) ly[j]-=d;
                    else slack[j]-=d;    
                }
            }
        }
        point ret=point(0,0);
        for (int i=1;i<=n;i++)
        {
            ret.a+=a[linky[i]][i];
            ret.b+=b[linky[i]][i];
        }
        if (ret<ans) ans=ret;
        return ret;
    }
    void DAC(point A,point B)
    {
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
                w[i][j]=a[i][j]*(A.b-B.b)+b[i][j]*(B.a-A.a);
        point C=KM();
        if ((C-A)*(B-A)<=0) return;
        DAC(A,C);DAC(C,B);
    }
    void work()
    {
        scanf("%d",&n);ans=point(inf,inf);
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
                scanf("%d",&a[i][j]);
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
                scanf("%d",&b[i][j]);
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
                w[i][j]=a[i][j];
        point A=KM();
        for (int i=1;i<=n;i++)    
            for (int j=1;j<=n;j++)
                w[i][j]=b[i][j];
        point B=KM();
        DAC(A,B);
        printf("%d
    ",ans.a*ans.b);
    }
    int main()
    {
        scanf("%d",&t);
        for (int i=1;i<=t;i++) work();
        return 0;    
    }
  • 相关阅读:
    一些鲜为人知的编程真相
    一些鲜为人知的编程真相
    Ruby 1.9不会杀死Python
    Boost.Asio和ACE之间关于Socket编程的比较
    Effective C++第17条:要在单独的语句中使用智能指针来存储由new创建的对象
    Ruby 1.9不会杀死Python
    Boost智能指针——weak_ptr
    对象生死劫 - 构造函数和析构函数的异常
    Protocol Buffers:Google 的数据交换格式
    根据出生日期计算年龄
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6354422.html
Copyright © 2020-2023  润新知