zoukankan      html  css  js  c++  java
  • poj 2112 Optimal Milking 网络流 最大流

    题目大意:农场有k个挤奶器,每个挤奶器最多容纳m头奶牛,所有奶牛和挤奶器之间的距离已知,安排奶牛挤奶方案使得所有奶牛中走的最大距离最小化。

    利用最大流来做,奶牛和挤奶器看做图中节点,先用floyd算出每个节点之间的最小距离,二分最大距离d,然后建图,边长大于d的都去掉,然后建立网络,引入源点和汇点,源点到每个奶牛节点连接一条容量为一的边,挤奶器节点与汇点连接一条容量为m的边,奶牛节点与挤奶器节点间连接容量为一的边(如果之间有边的话),然后求最大流,不断二分。

    代码为dinic算法

    #include <stdio.h>
    #include <string.h>
    #define MAX 300
    #define INF 10000000
    int dis[MAX][MAX],map[MAX][MAX];
    bool sign[MAX][MAX],used[MAX];
    int K,C,n,M;
    int min(int a,int b)
    {
    	if(a>b)
    		return b;
    	else return a;
    }
    void build(int mid)
    {
    	int i,j;
    	memset(map,0,sizeof(map));
    	for(i=K+1;i<=n;i++) map[0][i]=1;
    	for(i=1;i<=K;i++) map[i][n+1]=M;
    	for(i=K+1;i<=n;i++)
    	{
    		for(j=1;j<=K;j++)
    			if(dis[i][j]<=mid)
    				map[i][j]=1;
    	}
    }
    
    bool bfs()
    {
    	memset(used,0,sizeof(used));
    	memset(sign,0,sizeof(sign));
    	int queue[100*MAX]={0};
    	queue[0]=0;
    	used[0]=1;
    	int t=1,f=0;
    	while(f<t)
    	{
    		for(int i=0;i<=n+1;i++)
    		{
    			if(!used[i]&&map[queue[f]][i])
    			{
    				queue[t++]=i;
    				used[i]=1;
    				sign[queue[f]][i]=1;
    			}
    		}
    		f++;
    	}
    	if(used[n+1]) return true;
    	else return false;
    }
    
    int dfs(int v,int sum)
    {
    	int i,s,t;
    	if(v==n+1) return sum;
    	s=sum;
    	for(i=0;i<=n+1;i++)
    	{
    		if(sign[v][i])
    		{
    			t=dfs(i,min(map[v][i],sum));
    			map[v][i]-=t;
    			map[i][v]+=t;
    			sum-=t;
    		}
    	}
    	return s-sum;
    }
    
    int main()
    {
    	int i,j,k,l,r,mid,ans;
    	scanf("%d%d%d",&K,&C,&M);
    	n=K+C;
    	for(i=1;i<=n;i++)
    	{
    		for(j=1;j<=n;j++)
    		{
    			scanf("%d",&dis[i][j]);
    			if(dis[i][j]==0) dis[i][j]=INF;
    		}
    	}
    	for(k=1;k<=n;k++)
    		for(i=1;i<=n;i++)
    			for(j=1;j<=n;j++)
    				if(dis[i][j]>dis[i][k]+dis[k][j])
    					dis[i][j]=dis[i][k]+dis[k][j];
    	l=0;r=10000;
    	while(l<r)
    	{
    		mid=(l+r)/2;
    		ans=0;
    		build(mid);
    		while(bfs()) ans+=dfs(0,INF);
    		if(ans>=C) r=mid;
    		else l=mid+1;
    	}
    	printf("%d
    ",r);
    	return 0;
    }
    


     

     

  • 相关阅读:
    UBUNTU 自动挂载 NTFS
    automake autoconf 学习笔记(转载)
    error: X11/extensions/XInput.h: No such file or directory
    error: undefined macro: AC_PROG_LIBTOOL
    Linux下tar.xz结尾的文件的解压方法
    Ubuntu 修改hosts
    ubuntu主目录下的中文文件夹名改回英文
    ./configure: No such file or directory
    Ubuntu下GTK的安装、编译和测试
    图像适配源码
  • 原文地址:https://www.cnblogs.com/vermouth/p/3710209.html
Copyright © 2011-2022 走看看