• bzoj 3597: [Scoi2014]方伯伯运椰子 0/1分数规划


    3597: [Scoi2014]方伯伯运椰子

    Time Limit: 30 Sec  Memory Limit: 64 MB
    Submit: 144  Solved: 78
    [Submit][Status][Discuss]

    Description

     .................

    Input

     第一行包含二个整数N,M

    接下来M行代表M条边,表示这个交通网络
    每行六个整数,表示Ui,Vi,Ai,Bi,Ci,Di
    接下来一行包含一条边,表示连接起点的边

    Output

    一个浮点数,保留二位小数。表示答案,数据保证答案大于0

    Sample Input

    5 10
    1 5 13 13 0 412
    2 5 30 18 396 148
    1 5 33 31 0 39
    4 5 22 4 0 786
    4 5 13 32 0 561
    4 5 3 48 0 460
    2 5 32 47 604 258
    5 7 44 37 75 164
    5 7 34 50 925 441
    6 2 26 38 1000 22

    Sample Output

    103.00

    HINT

     1<=N<=5000

    0<=M<=3000
    1<=Ui,Vi<=N+2
    0<=Ai,Bi<=500
    0<=Ci<=10000
    0<=Di<=1000
     
      根本搞不懂网上的什么消圈算法,我的思路是这样的:不用想先肯定是枚举答案若ans<delta/tot,那么delta-ans*tot>0,我们先将所有有流的边假设退掉,然后将每条边分为撤销默认操作和新的扩边操作,这样可以直接通过0/1分数规划套费用流解决了,具体怎么加加减减比较烦人,可以直接参考代码。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 5100
    #define MAXE MAXV*20
    #define MAXV MAXN*2
    #define inf 1e100
    #define INF 0x3f3f3f3f
    #define eps 1e-4
    typedef double real;
    struct Edge
    {
            int np;
            int val;
            real cost;
            Edge *neg,*next;
    }E[MAXE],*V[MAXV];
    int tope=-1;
    int sour=0,sink=1;
    
    void addedge(int x,int y,int v,real c)
    {
    //        cout<<"Add: "<<x<<" "<<y<<" "<<v<<" "<<c<<endl;
            E[++tope].np=y;
            E[tope].val=v;
            E[tope].cost=c;
            E[tope].next=V[x];
            V[x]=&E[tope];
    
            E[++tope].np=x;
            E[tope].val=0;
            E[tope].cost=-c;
            E[tope].next=V[y];
            V[y]=&E[tope];
    
            V[x]->neg=V[y];
            V[y]->neg=V[x];
    }
    int q[MAXV*20];
    int vis[MAXV],vistime;
    real dis[MAXV];
    Edge *prve[MAXV];
    int prv[MAXV];
    int n,m;
    bool spfa()
    {
            int now=sour;
            Edge *ne;
            for (int i=0;i<MAXV;i++)
                    dis[i]=-inf;
            dis[now]=0;
            vis[now]=++vistime;
            q[0]=now;
            int head=-1,tail=0;
            while (head<tail)
            {
                    now=q[++head];
                    vis[now]=0;
                    for (ne=V[now];ne;ne=ne->next)
                    {
                            if (ne->val && dis[ne->np]<dis[now]+ne->cost)
                            {
                                    dis[ne->np]=dis[now]+ne->cost;
                                    prv[ne->np]=now;
                                    prve[ne->np]=ne;
                                    if (vis[ne->np]!=vistime)
                                    {
                                            vis[ne->np]=vistime;
                                            q[++tail]=ne->np;
                                    }
                            }
                    }
            }
            return dis[sink]!=-1e100;
    }
    pair<int,real> cost_flow()
    {
            int x;
            int totf=0;
            real sumc=0;
            int maxf;
            while (spfa())
            {
                    maxf=INF;
                    for (x=sink;x!=sour;x=prv[x])
                            maxf=min(maxf,prve[x]->val);
                    for (x=sink;x!=sour;x=prv[x])
                    {
                            prve[x]->val-=maxf;
                            prve[x]->neg->val+=maxf;
                    }
                    sumc+=maxf*dis[sink];
                    totf+=maxf;
            }
            return make_pair(totf,sumc);
    }
    struct edge
    {
            int x,y,vdec,vinc,vcur,vcst;
    }e[MAXE];
    int main()
    {
            //freopen("input.txt","r",stdin);
            int x,y,z;
            scanf("%d%d",&n,&m);
            sour=n+1;
            sink=n+2;
            int mxflow;
            for (int i=0;i<m;i++)
            {
                    scanf("%d%d%d%d%d%d",&e[i].x,&e[i].y,&e[i].vdec,&e[i].vinc,&e[i].vcur,&e[i].vcst);
                    if (e[i].x==sour)
                            mxflow=e[i].vcur;
            }
            double l,r,mid;
            l=0,r=40000;
            while (l+eps<r)
            {
                    memset(V,0,sizeof(V));
                    tope=-1;
                    mid=(l+r)/2;
                    double res=0;
                    for (int i=0;i<m;i++)
                    {
                            addedge(e[i].x,e[i].y,e[i].vcur,e[i].vdec-e[i].vcst+mid);
                            addedge(e[i].x,e[i].y,mxflow-e[i].vcur,-e[i].vinc-e[i].vcst-mid);
                            res+=e[i].vcur*(-e[i].vdec+e[i].vcst-mid);
                    }
                    res+=cost_flow().second;
                    if (res<=0)
                            r=mid;
                    else
                            l=mid;
            }
            printf("%.2lf
    ",l);
            return 0;
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    css样式之补充
    css样式之属性操作
    css之操作属性
    前端基础之css样式(选择器)
    mysql之视图,触发器,事务等
    pymysql模块
    MySQL之IDE工具介绍及数据备份
    mysql老是停止运行该怎么解决
    mysql之索引原理与慢查询优化
    MySQL 5.7.9版本sql_mode=only_full_group_by问题
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4364635.html
Copyright © 2020-2023  润新知