caioj.cn 1119网络流入门5:牛挤奶

1119: [视频]网络流入门5:牛挤奶

时间限制: 1 Sec  内存限制: 128 MB
提交: 74  解决: 26
[ 提交][ 状态][ 讨论版]

题目描述

  

【题目描述】

FJ把K个挤奶机搬进了住着C头奶牛的牧场。挤奶机的编号为1~K,奶牛的编号为K+1~~K+C。每头奶牛到每台挤奶机距离不同。每台挤奶机每天最多服务M头奶牛。求一种分配方案, 使得走得最远的奶牛走过的距离最小化。输出此距离.

【输入格式】

数据第1行是3个整数K,C,M(1≤K≤30)(1≤C≤200)(1≤M≤15)

接下来是一个(K+C)×(K+C)的距离矩阵。矩阵元素为正并不超200。距离为0表示两个点之间无边存在。

【输出格式】

输出一个整数,即走得最远的奶牛走过的距离的最小化值。

【样例输入】

2 3 2

0 3 2 1 1

3 0 3 2 0

2 3 0 1 0

1 2 1 0 2

1 0 0 2 0

【样例输出】

2

这一道题还是和前一道题一样,设置原点和汇点,用floyd查找最短路径,二分查找中用网络流判断

思路就不说了

#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
    int x,y,c,next,other;
}a[110000];
int len,last[110000],st,ed;
void ins(int x,int y,int c)
{
    int k1,k2;
    len++;k1=len;
    a[len].x=x;a[len].y=y;a[len].c=c;
    a[len].next=last[x];last[x]=len;
    len++;k2=len;
    a[len].x=y;a[len].y=x;a[len].c=0;
    a[len].next=last[y];last[y]=len;
    a[k1].other=k2;
    a[k2].other=k1;
}
int list[410],head,tail,h[410];
bool bt_h()
{
    memset(h,0,sizeof(h));h[st]=1;
    list[1]=st;head=1;tail=2;
    while(head!=tail)
    {
        int x=list[head];
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(a[k].c>0 && h[y]==0)
            {
                h[y]=h[x]+1;
                list[tail++]=y;
            }
        }
        head++;
    }
    if(h[ed]>0)return true;
    else return false;
}
int mymin(int x,int y)
{
    return x<y?x:y;
}
int findflow(int x,int f)
{
    if(x==ed)return f;
    int s=0,t;
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(a[k].c>0 && h[y]==(h[x]+1) && s<f)
        {
            s+=(t=findflow(y,mymin(a[k].c,f-s)));
            a[k].c-=t;
            a[a[k].other].c+=t;
        }
    }
    if(s==0)h[x]=0;
    return s;
}
int K,C,M;
int map[310][310];
int check(int x)
{
	len=0;memset(last,0,sizeof(last));
	for(int i=K+1;i<=K+C;i++)
	{
		for(int j=1;j<=K;j++)
		{
			if(map[i][j]<=x) 
				ins(i,j,1);
		}
	}
	for(int i=1;i<=K;i++)
	{
		ins(i,ed,M); 
	}
	for(int i=K+1;i<=K+C;i++)
	{
		ins(st,i,1);
	}
	int s=0;
	while(bt_h()==true) s=s+findflow(st,999999999);
	return s;
}
int main()
{
    scanf("%d%d%d",&K,&C,&M);
    st=K+C+1;ed=st+1;
    for(int i=1;i<=K+C;i++)
    {
    	for(int j=1;j<=K+C;j++)
    	{
    		scanf("%d",&map[i][j]);
    		if(map[i][j]==0) map[i][j]=999999999;
    	}
    }
    for(int k=1;k<=K+C;k++)
    	for(int i=1;i<=K+C;i++) if(i!=k)
    		for(int j=1;j<=K+C;j++) if(i!=j && j!=k)
    			if(map[i][j]>map[i][k]+map[k][j])
    			 	map[i][j]=map[i][k]+map[k][j];
	int l,r,mid,ans;
	l=1;r=200*230;
	while(l<=r)
	{
		mid=(l+r)/2;
		if(check(mid)==C)
		{
			r=mid-1;ans=mid;
		}
		else
		{
			l=mid+1;
		}
	}
	printf("%d\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zsyzClb/article/details/80986618
cn
今日推荐