zoukankan      html  css  js  c++  java
  • poj2112(网络流-最大流+二分)

    题意:给你k个挤奶器,c头牛,每个挤奶器能放m头牛,问你奶牛需要走的最大距离最小是多少;

    解题思路:因为最大距离最小,也就是求最小的距离满足所有牛都能到,所以我们先用floyd跑最短路,把所有点之间的距离算出来后再,对答案进行二分:牛和挤奶器的距离<=二分值的可以连一条边,容量为1;

    然后源点和奶牛连一条容量为1的边,挤奶器和汇点连一条容量为m的边,所以二分只是为了看奶牛是否能到达某个挤奶器;

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #include<cstdio>
    #define maxn 100500
    #define inf 0x3f3f3f3f
    using namespace std;
    struct Edge
    {
        int next;
        int to;
        int w;
        int fa;
    }edge[maxn];
    int head[maxn];
    int x,y;
    int dist[505][505];
    int cnt;
    int n,m,Start,End;
    int k,c;
    int depth[maxn];
    void floyd()
    {
        for(int l=1;l<=c+k;l++)
        {
            for(int i=1;i<=c+k;i++)
            {
                for(int j=1;j<=c+k;j++)
                {
                    if(dist[i][j]>dist[i][l]+dist[l][j])
                        dist[i][j]=dist[i][l]+dist[l][j];
                }
            }
        }
    }
    void add(int u,int v,int w)
    {
        edge[cnt].next=head[u];edge[cnt].to=v;
        edge[cnt].fa=u;edge[cnt].w=w;head[u]=cnt++;
        edge[cnt].next=head[v];edge[cnt].w=0;
        edge[cnt].to=u;edge[cnt].fa=v;head[v]=cnt++;
    }
    bool bfs()
    {
        memset(depth,0,sizeof(depth));
        queue<int>q;
        q.push(Start);
        depth[Start]=1;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=head[u];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to;
                if(depth[v]||edge[i].w<=0)
                    continue;
                depth[v]=depth[u]+1;
                q.push(v);
            }
        }
        return depth[End];
    }
    int dfs(int u,int maxflow)
    {
        if(u==End)
            return maxflow;
        int add=0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if(depth[v]!=depth[u]+1)
                continue;
            if(edge[i].w==0)
                continue;
            int tempflow=dfs(v,min(edge[i].w,maxflow-add));
            edge[i].w-=tempflow;
            edge[i^1].w+=tempflow;
            add+=tempflow;
        }
        return add;
    }
    int dinic()
    {
        int ans=0;
        while(bfs())
        {
            ans+=dfs(Start,inf);
        }
        return ans;
    }
    void buildmap(int value)
    {
        memset(head ,-1,sizeof(head));
        cnt=0;
        for(int i=k+1;i<=k+c;i++)
        {
            add(0,i,1);
        }
        for(int i=k+1;i<=k+c;i++)
        {
            for(int j=1;j<=k;j++)
            {
                if(dist[i][j]<=value)
                {
                    add(i,j,1);
                   // cout<<i<<" "<<j<<endl;
                }
            }
        }
        for(int i=1;i<=k;i++)
        {
            add(i,k+c+1,m);
        }
    }
    int main()
    {
        scanf("%d%d%d",&k,&c,&m);
        Start=0;End=k+c+1;
        for(int i=1;i<=k+c;i++)
        {
            for(int j=1;j<=k+c;j++)
            {
                scanf("%d",&dist[i][j]);
                if(dist[i][j]==0)
                    dist[i][j]=inf;
            }
        }
        floyd();
        int l=0,r=10000;
        while(l<r)
        {
            int mid=(l+r)/2;
            buildmap(mid);
            int xx=dinic();
            if(xx>=c)
            {
                r=mid;
            }
            else
            {
                    l=mid+1;
            }
        }
        printf("%d
    ",r);
    }
    

      

  • 相关阅读:
    网页前端开发,对于图片慢加载简介
    createDocumentFragment
    mobile端
    Handler对象
    移动应用表单设计秘籍
    【194】Windows 上使用 wget
    【193】◀▶ PowerShell 官方资料索引
    【192】PowerShell 相关知识
    【191】◀▶ Powershell 命令集 Cmdlets
    高性能MySql进化论(九):查询优化器常用的优化方式
  • 原文地址:https://www.cnblogs.com/huangdao/p/9304470.html
Copyright © 2011-2022 走看看