zoukankan      html  css  js  c++  java
  • HDU-4807-Lunch Time(二分+费用流,思维)

      这道题非常好,如果没有真正弄懂费用流算法的人,只会套模版的人是肯定做不出来的。

      我们其实这样考虑,费用流真正的思想是吧费用作为长度,然后跑最短路,同时保证路上的流量不为0,也就是增广;

      跑到终点后,回溯把路上的流量进行修改。一直这样下去直到无法增广。

      这道题也是一样,我们把路径长度看成费用,路径限制看成流量限制。

      每次增广到终点后,得到的dis[t]代表源点到汇点的路径长度,incf[t]代表的是这条路上的流量限制。

      每一次增广成功,我们都会获得一个和之前不同的路径。

      这样我们就能够得到所有s-t路径长度,以及长度对应的流量限制。并且他们所有路径都是满足在流量限制条件下的。

      然后其实就很简单了,我们知道我们需要运输的人数,同时知道每一条路径对应的路径的路径运输能力和路径长度,那么我们对答案进行二分,也就是对总共用的时间进行二分。

      对于所有路径长度是>=总共运输时间的(每次速度为1),也就是说对于当前的时间内,这条路是可以运载一些人到终点的,那么这条路运输的人数其实就是  e[i].flow*(t-e[i].dist+1)

     也就是当前道路的流量*(所用的时间-从起点到终点的时间+1),因为当前道路的在前dist-1的时间内,人还在路上,没有抵达,在dist时间以后,人会源源不断的来到。

    注意k可能是0,需要先特判k=0,再特判最大流量=0。不然会错。。。

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    #define LL long long
    using namespace std;
    const int maxx = 2e5+6;
    const LL INF = 1e18;
    int ver[maxx],head[maxx],Next[maxx];
    LL incf[maxx];
    LL cost[maxx],edge[maxx];
    int v[maxx],pre[maxx];
    LL d[maxx];
    int tot,cnt,n,m,s,t;
    LL ans,k,maxflow;
    struct node
    {
        LL flow;
        LL w;
    } a[maxx];
    void add(int x,int y,LL z,LL c)
    {
        ver[++tot]=y;
        edge[tot]=z;
        cost[tot]=c;
        Next[tot]=head[x];
        head[x]=tot;
        ver[++tot]=x;
        edge[tot]=0;
        cost[tot]=-c;
        Next[tot]=head[y];
        head[y]=tot;
    }
    bool spfa()
    {
        queue<int>q;
        while(q.size())q.pop();
        for (int i=1; i<=n+5; i++)
        {
            d[i]=INF;
            v[i]=0;
        }
        q.push(s);
        d[s]=0;
        v[s]=1;
        incf[s]=INF;
        while(q.size())
        {
            int x=q.front();
            v[x]=0;
            q.pop();
            for (int i=head[x]; i; i=Next[i])
            {
                if (!edge[i])
                    continue;
                int y=ver[i];
                //cout<<x<<" "<<y<<" "<<edge[i]<<endl;
                if(d[y]>d[x]+cost[i])
                {
                    d[y]=d[x]+cost[i];
                    incf[y]=min(incf[x],edge[i]);
                    pre[y]=i;
                    if(!v[y])v[y]=1,q.push(y);
                }
            }
        }
        if(d[t]==INF)return false;
        else return true;
    }
    void update()
    {
        int x=t;
        cnt++;
        a[cnt].w=d[t];
      //  cout<<t-1<<"---"<<incf[t]<<"--"<<d[t]<<endl;
        a[cnt].flow=incf[t];
        while(x!=s)
        {
            int i=pre[x];
            edge[i]-=incf[t];
            edge[i^1]+=incf[t];
            x=ver[i^1];
       //     printf("%d-->",x-1);
        }
      //  cout<<endl;
        maxflow+=incf[t];
    }
    bool check(LL x)
    {
        LL sum=0;
        for (int i=1; i<=cnt; i++)
        {
            if (a[i].w<=x)
            {
                sum+=(LL)a[i].flow*(x-a[i].w+1);
            }
        }
        return sum>=k;
    }
    int main()
    {
        int uu,vv,c;
        while(~scanf("%d%d%lld",&n,&m,&k))
        {
            cnt=0;
            tot=1;
            maxflow=0;
            s=1;
            t=n;
            memset(head,0,sizeof(head));
            for (int i=1; i<=m; i++)
            {
                scanf("%d%d%d",&uu,&vv,&c);
                add(uu+1,vv+1,c,1);
            }
            while(spfa())update();
            if (k==0)
            {
                printf("0
    ");
            }
            else if (maxflow==0){
                printf("No solution
    ");
            }else {
                int l=1,r=1e9;
                while(l<=r)
                {
                    int mid=(l+r)>>1;
                    if (check(mid))
                    {
                        r=mid-1;
                        ans=mid;
                    }
                    else
                    {
                        l=mid+1;
                    }
                }
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }

      

  • 相关阅读:
    IE浏览器下常见的CSS兼容问题
    Android studio 使用问题汇总
    IOS中的属性列表----Property List
    自定义组件-BreadcrumbTreeView 的使用
    IOS开发之数据sqlite使用
    深入分析动态管理Fragment
    IOS开发中多线程的使用
    Java中导入、导出Excel
    IOS数据持久化之归档NSKeyedArchiver
    Bugfree3.0.4 Linux环境安装指南
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/11611442.html
Copyright © 2011-2022 走看看