zoukankan      html  css  js  c++  java
  • poj 2112 Optimal Milking(二分+floyd+最大流)

      题目大意就是k个机器和c头牛组成K+C个点,还有个m表示一个机器最多给m头牛服务,然后给你一个(K+C)*(K+C)的矩阵描述了任意2个物体之间的边关系,边权为0表示无边。然后要你在c头牛都能找到机器配对的前提下求c头牛到机器的最远距离的最小值,先把k个机器和c头牛看成是K+C个点,方法就是跑个floyd先求出任意2个点之间的最短距离,然后在二分最远距离的最小值,设low为0,up为100000,这个设的范围包含解在内即可,然后依据mid来建网络流的图,mid表示牛到机器的最远距离,意思是要是i牛到j机器的距离超过了mid,则i牛不能和j机器匹配,即i到j的这条边的容量为0,还有这种多源多汇的最大流还有设个超级源点st,超级汇点et,将et和k个机器连,容量为m(因为每个机器最多服务m头牛),再将st和c头牛连,容量为1,因为1头牛只能匹配一台机器。建完之后就用dinic跑网络了(这也是我第一次用dinic求最大流,没想到一发就过了)。求出来的最大流<c则说明mid太小了,则low=mid+1,否则的话说明最远距离的最小值可能比mid还要小,则up=mid,最后二分搜索结束up就是答案。

    #include<iostream>
    #include<string.h>
    #include<queue>
    #include<stdlib.h>
    using namespace std;
    #define maxn 250
    #define inf 0x3f3f3f3f
    int dis[maxn][maxn],cap[maxn][maxn],depth[maxn];
    int k,c,m;
    int n,st,et;
    int cnt=0;
    void floyd()
    {
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    }
    void build(int maxx)
    {
        for(int i=0;i<=n+1;i++)//正边反边容量清空
            for(int j=i;j<=n+1;j++)
            {
                cap[i][j]=cap[j][i]=0;
            }
        for(int i=k+1;i<=n;i++)//建图
            cap[st][i]=1;
        for(int i=1;i<=k;i++)
            cap[i][et]=m;
        for(int i=k+1;i<=n;i++)
            for(int j=1;j<=k;j++)
            {
                if(dis[i][j]<=maxx)
                {
                    cap[i][j]=1;
                }
    
            }
    }
    bool bfs()//能不能分层等价于该网络流还有没有增广路
    {
        queue<int>q;
        for(int i=st;i<=et;i++)
            depth[i]=0;
        depth[st]=1;
        q.push(st);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int v=st;v<=et;v++)
                if(!depth[v]&&cap[u][v]>0)
                {
                    depth[v]=depth[u]+1;
                    q.push(v);
    
                }
        }
        if(depth[et]==0)
            return false;
        return true;
    }
    int dfs(int u,int f)
    {
        if(u==et)
            return f;
        for(int v=st;v<=et;v++)
        {
            if((depth[v]==depth[u]+1)&&cap[u][v])
            {
                int ff=dfs(v,min(f,cap[u][v]));
                if(ff>0)
                {
                    cap[u][v]-=ff;
                    cap[v][u]+=ff;
                    return ff;
                }
            }
        }
        return 0;
    
    
    }
    int dinic()
    {
        int maxflow=0;
        while(bfs())
        {
            int d;
            while(d=dfs(st,inf))
            {
                //cnt++;
            //cout<<"/第"<<cnt<<"/条增广路  "<<d<<endl;
                maxflow+=d;
            }
        }
        return maxflow;
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        while(cin>>k>>c>>m)
        {
            if(!k&&!c&&!m) break;
            n=k+c;
            st=0;
            et=k+c+1;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                {
                    cin>>dis[i][j];
                    if(!dis[i][j])
                        dis[i][j]=inf;
    
                }
            floyd();
            int low,mid,up,flow;
            low=0;
            up=10000;
            while(low<up)
            {
                mid=(low+up)>>1;
                build(mid);
                flow=dinic();
                if(flow<c)
                    low=mid+1;
                else
                    up=mid;
                //cout<<"low:"<<low<<"    up:"<<up;
                //cout<<"  maxflow :"<<flow<<endl;
                //system("pause");
                //cout<<endl;
    
            }
            //cout<<"/maxflow  "<<flow<<endl;
            cout<<up<<endl;
    
    
        }
    }
    

    附上大佬的dinic算法讲解博客

    https://www.cnblogs.com/SYCstudio/p/7260613.html

  • 相关阅读:
    eclipse中的Invalid text string (xxx).
    在jsp文件中出现Unknown tag (c:out)
    eclipse 界面复原
    ecilpse 纠错插件
    Multiple annotations found at this line:- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
    Port 8080 required by Tomcat v9.0 Server at localhost is already in use. The server may already be running in another process, or a system process may be using the port.
    调用第三方https接口
    调用第三方http接口
    创建带值枚举
    spring整合redis之Redis配置文件
  • 原文地址:https://www.cnblogs.com/eason9906/p/11755018.html
Copyright © 2011-2022 走看看