zoukankan      html  css  js  c++  java
  • BZOJ 4819 [Sdoi2017]新生舞会 ——费用流 01分数规划

    比值最大 分数规划

    二分答案之后用费用流进行验证。

    据说标称强行乘以1e7换成了整数的二分。

    不过貌似实数二分也可以过。

    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    #define ll long long
    #define mp make_pair
    #define eps 1e-7
    #define inf 1e9
    #define maxn 50005
     
    int h[maxn],to[maxn],ne[maxn],en=0,fl[maxn],n,S=maxn-2,T=maxn-1;
    double cost[maxn],a[101][101],b[101][101],dis[maxn];
    int with[maxn],minn[maxn],inq[maxn];
     
    void add(int a,int b,double c,int d)
    {
        to[en]=b;ne[en]=h[a];fl[en]=d;cost[en]=c; h[a]=en++;
        to[en]=a;ne[en]=h[b];fl[en]=0;cost[en]=-c;h[b]=en++;
    }
     
    queue <int> q;
     
    bool SPFA()
    {
        F(i,1,2*n) dis[i]=inf; dis[S]=inf; dis[T]=inf;
        memset(inq,0,sizeof inq);
        memset(with,0,sizeof with);
        memset(minn,0x3f,sizeof minn);
        q.push(S); inq[S]=1; dis[S]=0;
        while (!q.empty())
        {
            int x=q.front(); q.pop(); inq[x]=0;
            for (int i=h[x];i>=0;i=ne[i])
                if (dis[to[i]]>dis[x]+cost[i]&&fl[i]>0)
                {
                    dis[to[i]]=dis[x]+cost[i];
                    minn[to[i]]=min(minn[x],fl[i]);
                    with[to[i]]=i;
                    if (!inq[to[i]]) q.push(to[i]),inq[to[i]]=1;
                }
        }
        return dis[T]<inf-eps;
    }
     
    double zeng()
    {
        for (int i=T;i!=S;i=to[with[i]^1])
        {
            fl[with[i]]-=minn[T];
            fl[with[i]^1]+=minn[T];
        }
        return minn[T]*dis[T];
    }
     
    double dinic()
    {
        double ret=0,tmp;
        while (SPFA())
        {
            tmp=zeng();
            ret+=tmp;
        }
        return ret;
    }
     
    bool check(double d)
    {
        memset(h,-1,sizeof h);
        en=0;
        F(i,1,n) add(S,i,0,1);
        F(i,1,n) add(i+n,T,0,1);
        F(i,1,n) F(j,1,n) add(i,j+n,d*b[i][j]-a[i][j],1);
        double ret=dinic();
        if (ret<0) return true;
        return false;
    }
     
    int main()
    {
        scanf("%d",&n);
        F(i,1,n) F(j,1,n) scanf("%lf",&a[i][j]);
        F(i,1,n) F(j,1,n) scanf("%lf",&b[i][j]);
        double l=0,r=1e4;
        while (fabs(l-r)>eps)
        {
            double mid=(l+r)/2;
            if (check(mid)) l=mid;
            else r=mid;
        }
        printf("%.6lf
    ",(l+r)/2);
    }
    

      

  • 相关阅读:
    Interview with BOA
    Java Main Differences between HashMap HashTable and ConcurrentHashMap
    Java Main Differences between Java and C++
    LeetCode 33. Search in Rotated Sorted Array
    LeetCode 154. Find Minimum in Rotated Sorted Array II
    LeetCode 153. Find Minimum in Rotated Sorted Array
    LeetCode 75. Sort Colors
    LeetCode 31. Next Permutation
    LeetCode 60. Permutation Sequence
    LeetCode 216. Combination Sum III
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6737591.html
Copyright © 2011-2022 走看看