• BZOJ3130 [Sdoi2013]费用流


    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=3130

    这题codevs上也有,不过数据挂了[要A得看discuss]。

    题目大意:

    Alice来弄一条最大流,Bob来给Alice弄好的最大流定权值。

    定权值的方法是给没条边定一个值wi,然后wi*flow(i)的和就是总的费用,但要求所有wi之和为p。

    现在Bob希望最后的费用最大,即对于每一种最大流方案都会有一种最大的定值方案。

    Alice则希望花费最小,即选出一种最大流方案,使得这种方案的最大定值是所有最大流方案中最小的。

    求最大流,及这个最小的最大定值。

    首先我们先从Bob的角度出发。

    怎么给一种最大流方案定值就能最大呢?

    显然是给最大流中流量最大的边订上p的值就可以了。

    因为最后也是加法,然后满足分配率,然后随便证一下,感受一下就是对的了。

    然后从Alice的角度来想,恩不就是让流量最大的边最小么?...

    然后就限制流量跑最大流啊,如果和原来相同就可以了。

    这个流量限制就是典型的二分咯...不过注意往常的网络流都是跑整数流量,但是这题不是,我们要实数二分最大流量

    因为往常边都是整数的边,最大流跑整数的一定可以跑出来,不过现在毕竟限流的情况,那么我们要跑小数咯...

    如果你还不信,给你一个样例好了[来自ZYF-ZYF]:

    所以呢= =大家注意精度控制好了...不懂看看代码也行。

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    const int maxn=110;
    const int maxm=1010;
    const int INF=0x3f3f3f3f;
    const double eps=1e-6;
    
    struct Node{
        int data,next;
        double low;
    }node[maxm<<1];
    
    #define now node[point].data
    #define www node[point].low
    #define then node[point].next
    
    struct Edge{
        int u,v;
        double w;
    }edge[maxm];
    
    int n,m,p,cnt;
    int s,t;
    double ans;
    int dis[maxn],que[maxn];
    int head[maxn],cur[maxn];
    
    void add(int u,int v,double w){
        node[cnt].data=v;node[cnt].next=head[u];node[cnt].low=w;head[u]=cnt++;
        node[cnt].data=u;node[cnt].next=head[v];node[cnt].low=0;head[v]=cnt++;
    }
    
    bool BFS(){
        memset(dis,-1,sizeof(dis));
        int H=0,T=1;que[1]=1;dis[1]=0;
        while(H<T){
            H++;
            for(int point=head[que[H]];point!=-1;point=then)
                if(www>eps && dis[now]<0){
                    dis[now]=dis[que[H]]+1;
                    que[++T]=now;
                }
        }
        return dis[t]>0;
    }
    
    double dfs(int x,double low){
        if(x==t) return low;
        double Low;
        for(int &point=cur[x];point!=-1;point=then)
            if(www>eps && dis[now]==dis[x]+1){
                Low=dfs(now,min(low,www));
                if(Low>eps){
                    www-=Low,node[point^1].low+=Low;
                    return Low;
                }
            }
        return 0;
    }
    
    double check(double mid){
        cnt=0;
        for(int i=1;i<=n;i++) head[i]=-1;
        for(int i=1;i<=m;i++)
            add(edge[i].u,edge[i].v,min(edge[i].w,mid));
        
        double flag,sum=0;
        while(BFS()){
            memcpy(cur,head,sizeof(head));
            while((flag=dfs(s,INF))>eps)
                sum+=flag;
        }
        return sum;
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("3130.in","r",stdin);
        freopen("3130.out","w",stdout);
    #endif
        int u,v,w;
        double l=0,r=0,mid;
    
        scanf("%d%d%d",&n,&m,&p);
        s=1,t=n;
        for(int i=1;i<=n;i++) head[i]=-1;
        for(int i=1;i<=m;i++)
            scanf("%d%d%lf",&edge[i].u,&edge[i].v,&edge[i].w),r=max(r,edge[i].w);
        
        ans=check(r);
        while(r-l>eps){
            mid=(l+r)/2;
            if(fabs(ans-check(mid))<eps) r=mid;
            else l=mid;
        }
        
        printf("%.0lf
    %.5lf",ans,l*p);
        
        return 0;
    }
    View Code
  • 相关阅读:
    JavaScript知识点总结
    Python错误:ImportError: No module named 'requests'
    The type java.lang.CharSequence cannot be resolved. It is indirectly referenced from required .class
    Html重点知识
    使用Gson中的JsonElement所遇到的坑
    AndroidStudio:The number of method references in a .dex file cannot exceed 64K错误
    使用TextUtils.isEmpty()遇到的坑
    Gson常用方法
    AndroidStudio——java.lang.UnsatisfiedLinkError错误
    RecyclerView点击,移动到中间位置
  • 原文地址:https://www.cnblogs.com/Robert-Yuan/p/5222986.html
Copyright © 2020-2023  润新知