zoukankan      html  css  js  c++  java
  • Codeforces Round #381 (Div. 1) E

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<iostream>
    using namespace std;
    const int maxn=200010;
    const double eps=1e-8;
    
    #define sadf 123124
    #define int long long
    bool vis[maxn];
    double n,m,x,y,z,f,cost[maxn],pre[maxn],flow[maxn],maxflow,mincost;
    int s,t;
    int last[maxn];
    //cost最小花费;pre每个点的前驱;last每个点的所连的前一条边;flow源点到此处的流量
    //maxflow 最大流量
    //mincost 最大流量的情况下的最小花费
    struct Edge
    {
        int to,next;
        double flow,cost;//flow流量 cost花费
    } edge[maxn];
    int head[maxn],num_edge;
    queue <int> q;
    int aa,bb;
    int AA,BB;
    double qwq1[40010],qwq2[40010];
    #define INF 2147483647
    void add(int from,int to,int flow,double cost)
    {
        edge[++num_edge].next=head[from];
        edge[num_edge].to=to;
        edge[num_edge].flow=flow;
        edge[num_edge].cost=cost;
        head[from]=num_edge;
    
        edge[++num_edge].next=head[to];
        edge[num_edge].to=from;
        edge[num_edge].flow=0;
        edge[num_edge].cost=-cost;
        head[to]=num_edge;
    }
    double spfa(int s,int t)
    {
        for(int i=1; i<=t; ++i)
            cost[i]=-1;
        cost[s]=0;
        q.push(s);
        vis[s]=1;
        pre[t]=-1;
        flow[s]=2e9;//要加上这一条,不然到最后是flow都变为0  
        while (!q.empty())
        {
            int now=q.front();
            q.pop();
            vis[now]=0;
            for (int i=head[now]; i!=-1; i=edge[i].next)
            {
                if (edge[i].flow>eps && cost[edge[i].to]<cost[now]+edge[i].cost&&cost[now]+edge[i].cost-cost[edge[i].to]>eps)//正边
                {
                    cost[edge[i].to]=cost[now]+edge[i].cost;
                    pre[edge[i].to]=now;
                    last[edge[i].to]=i;
                    flow[edge[i].to]=min(flow[now],edge[i].flow);
                    if (!vis[edge[i].to])
                    {
                        vis[edge[i].to]=1;
                        q.push(edge[i].to);
                    }
                }
            }
        }
        return pre[t]!=-1;
    }
    
    void MCMF()
    {
        while (spfa(s,t))
        {
            int now=t;
            //回溯加的时候,要视情况,这个题,是把边的cost都加上
            //如果不把flow[s]初始化为正无穷,那么到t的时候,flow[t]就是0
            //若初始化为正无穷,就是1 
            maxflow+=flow[t]; 
            mincost+=flow[t]*cost[t];
            while (now!=s)
            {
    //            mincost+=edge[last[now]].cost*edge[last[now]].flow;
                edge[last[now]].flow-=1;//flow和cost容易搞混
                edge[last[now]^1].flow+=1;
                now=pre[now];
            }
        }
    }
    signed main()
    {
        memset(head,-1,sizeof(head));
        num_edge=1;
        cin>>n;
        cin>>aa>>bb;
        AA=n+1;
        BB=AA+1;
        s=BB+1;
        t=s+1;
        for(int i=1; i<=n; i++)
        {
            double x;
            cin>>x;
            qwq1[i]=x;
        }
        for(int i=1; i<=n; ++i)
        {
            double x;
            cin>>x;
            qwq2[i]=x;
        }
        add(s,AA,aa,0.0);
        add(s,BB,bb,0.0);
        for(int i=1; i<=n; i++)
        {
            add(AA,i,1,qwq1[i]);
            add(BB,i,1,qwq2[i]);
            add(i,t,1,0.0);
            add(i,t,1,-(qwq1[i]*qwq2[i]));
        }
        MCMF();
        printf("%.8lf
    ",mincost);
        return 0;
    }
  • 相关阅读:
    JavaBean 与 EJB 的区别
    MFC选项卡的实现
    MFC的图片按钮
    windows 下使用 MinGW + msys 编译 ffmpeg
    在windows使用vs2008编译live555
    C89 和 C99 标准比较
    11.求二元查找树的镜像[MirrorOfBST]
    10.排序数组中和为给定值的两个数字[Find2NumbersWithGivenSum]
    9.链表中倒数第k个结点[FindReverseKthLinkedListNode]
    8.另类方法求1+2+...+n[AnotherMethodOfCalculateSumN]
  • 原文地址:https://www.cnblogs.com/QingyuYYYYY/p/13192482.html
Copyright © 2011-2022 走看看