POJ2112_Optimal Milking(网洛流最大流Dinic+最短路Flody+二分)

解题报告

农场有k个挤奶机和c头牛,每头牛到每一台挤奶机距离不一样,每台挤奶机每天最多挤m头牛的奶。

寻找一个方案,安排每头牛到某一挤奶机挤奶,使得c头牛须要走的全部路程中的最大路程的最小值。

要使每一头牛都去挤奶,那么建完模型就要推断是否满流。

因为是多源多点的网络,如果源点0,汇点n+1(n=k+c)

源点到每一头牛的容量为1,每一台机器到汇点的容量为m;用flody求出随意一头牛到随意一台机器的最短路;

对于取最大距离的最小值能够用二分来找。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define inf 99999999
#define K 33
#define C 210
using namespace std;
int k,c,m,mmap[K+C][K+C],l[K+C],edge[K+C][K+C],n;
void flody()
{
    for(int l=1; l<=n; l++)
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                if(mmap[i][j]>mmap[i][l]+mmap[l][j])
                    mmap[i][j]=mmap[i][l]+mmap[l][j];
            }
        }
    }
}
int bfs()
{
    memset(l,-1,sizeof(l));
    queue<int>Q;
    Q.push(0);
    l[0]=0;
    while(!Q.empty())
    {
        int u=Q.front();
        Q.pop();
        for(int i=0; i<=n+1; i++)
        {
            if(edge[u][i]&&l[i]==-1)
            {
                l[i]=l[u]+1;
                Q.push(i);
            }
        }
    }
    if(l[n+1]>0)return 1;
    else return 0;
}
void G(int mid)
{
    int i,j;
    memset(edge,0,sizeof(edge));
    for(i=1; i<=k; i++)
        edge[i][n+1]=m;
    for(i=k+1; i<=n; i++)
        edge[0][i]=1;
    for(i=k+1; i<=n; i++)
    {
        for(j=1; j<=k; j++)
        {
            if(mmap[i][j]<=mid)
                edge[i][j]=1;
            else edge[i][j]=0;
        }
    }
}
int dfs(int x,int f)
{
    int a;
    if(x==n+1)return f;
    for(int i=0; i<=n+1; i++)
    {
        if(edge[x][i]&&l[i]==l[x]+1&&(a=dfs(i,min(f,edge[x][i]))))
        {
            edge[x][i]-=a;
            edge[i][x]+=a;
            return a;
        }
    }
    return 0;
}
int dinic(int mid)
{
    int ans=0,a;
    G(mid);
    while(bfs())
        while(a=dfs(0,inf))
            ans+=a;
    return ans;
}
int main()
{
    int i,j;
    while(~scanf("%d%d%d",&k,&c,&m))
    {
        n=k+c;
        for(i=1; i<=n; i++)
        {
            for(j=1; j<=n; j++)
            {
                scanf("%d",&mmap[i][j]);
                if(!mmap[i][j])
                    mmap[i][j]=inf;
            }
        }
        flody();
        int L=0,R=20000;
        while(L<R)
        {
            int mid=(L+R)/2;
            int ans=dinic(mid);
            if(ans>=c)R=mid;
            else L=mid+1;
        }
        printf("%d\n",R);
    }
    return 0;
}

Optimal Milking

Time Limit: 2000MS   Memory Limit: 30000K
Total Submissions: 11664   Accepted: 4238
Case Time Limit: 1000MS

Description

FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among the C (1 <= C <= 200) cows. A set of paths of various lengths runs among the cows and the milking machines. The milking machine locations are named by ID numbers 1..K; the cow
locations are named by ID numbers K+1..K+C.

Each milking point can "process" at most M (1 <= M <= 15) cows each day.

Write a program to find an assignment for each cow to some milking machine so that the distance the furthest-walking cow travels is minimized (and, of course, the milking machines are not overutilized). At least one legal assignment is possible for all input
data sets. Cows can traverse several paths on the way to their milking machine.

Input

* Line 1: A single line with three space-separated integers: K, C, and M.

* Lines 2.. ...: Each of these K+C lines of K+C space-separated integers describes the distances between pairs of various entities. The input forms a symmetric matrix. Line 2 tells the distances from milking machine 1 to each of the other entities; line 3 tells
the distances from machine 2 to each of the other entities, and so on. Distances of entities directly connected by a path are positive integers no larger than 200. Entities not directly connected by a path have a distance of 0. The distance from an entity
to itself (i.e., all numbers on the diagonal) is also given as 0. To keep the input lines of reasonable length, when K+C > 15, a row is broken into successive lines of 15 numbers and a potentially shorter line to finish up a row. Each new row begins on its
own line.

Output

A single line with a single integer that is the minimum possible total distance for the furthest walking cow.

Sample Input

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

Sample Output

2
时间: 2024-10-22 15:54:00

POJ2112_Optimal Milking(网洛流最大流Dinic+最短路Flody+二分)的相关文章

最大流算法(Edmons-Karp + Dinic 比较) + Ford-Fulkson 简要证明

Ford-Fulkson用EK实现:483ms #include <cstdio> #include <cstring> #define min(x,y) (x>y?y:x) int pre[105],q[105]; int F[105][105]; int n,nc,np,m,s,t,all; int MaxFlow(int s, int t){ int ans=0; while(1){ memset(pre,0,sizeof(pre)); int head=0,tail=

java021.io流 字符流

注意:字节流可以操作任意数据,但是字符流只能操作纯文本文件,一般用于文本文件的只读或只写! 字符流是什么 * 字符流是可以直接读写字符的IO流 * 字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要写出字符, 需要把字符转为字节再写出. FileReader类的read()方法可以按照字符大小读取FileWriter类的write()方法可以自动把字符转为字节写出 字符流用处和特点:* 字符流也可以拷贝文本文件, 但不推荐使用. 因为读取时会把字节转为字符, 写出时还要把字符转回字

转换流以及流规律总结

 转换流: 上边读取键盘录入的代码,与BufferedReader的readLine()方法很相似,那么能不能用readLine()来代替?因为System.in是字节流,它要使用字符流缓冲区的方法,这就需要使用到两个转换流:InputStreamReader和OutputStreamWriter. package tan; import java.io.*; public class TranStreamDemo { public static void main(String[] args)

字符流/转换流

字符流/转换流:由于字节流操作中文不方便,所以出现了. 总共有以下方法: 1.InputStreamReader.OutputStreamWriter 2.FileReader.FileWriter 3.BufferedReader BufferedWriter的普通方法 4.BufferedReader BufferedWriter的特殊方法 字符流=字节流+编码表 编码的方法: byte[] getBytes(String charsetName):使用指定的字符集合把字符编码成字节数组  

Java IO之处理流(缓冲流、转换流)

一.处理流: 增强功能,提供性能,在节点流之上. 二.节点流与处理流的关系 节点流(字节流.字符流)处于IO操作的第一线,所有操作必须通过它们进行: 处理流可以对其他流进行处理(提高效率或操作灵活性). 三.缓冲流 1.字节缓冲流 BufferedInputStream BufferedOutputStream package IOBuffer; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; im

黑马程序员——java基础---IO(input output)流字符流

黑马程序员——java基础---IO(input output)流字符流 ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- io(input output)流特点: 1,io流用来处理数据之间的传输 2,java对数据的操作是通过流的方式: 3,java用于操作流的对象都在io包中: 4,流按操作数据分为两种:字节流和字符流: 5,流按流向分为:输入流和输出流. 注意:流只能操作数据,而不能操作文件. 3.IO流的常用基类: 1)字节流的抽象

Java基础知识强化之IO流笔记37:字符流缓冲流之BufferedWriter / BufferedReader使用

1. 字符流缓冲流: 字符流为了高效读写,也提供了对应的字符缓冲流. BufferedWriter:字符缓冲输出流 BufferedReader:字符缓冲输入流 2. BufferedWriter使用:     将文本写入字符输出流,缓冲各个字符,从而提供单个字符.数组和字符串的高效写入.可以指定缓冲区的大小,或者接受默认的大小.在大多数情况下,默认值就足够大了. (1)BufferedWriter的构造方法: 构造方法摘要 BufferedWriter(Writer out)         

IO流常用方法,流的用法,代码例子

/** * 一个汉字是一个字符,就是2个字节,就是16位,所以,要读取汉字,还得用字符流 *-------------------------------------- 基础流---------------------------------------------- */FileInputStream ://(字节输入流,一次读取1个字节(就是8位)) FileInputStream fis = new FileInputStream("文件路径");//字节输入流 FileOutp

.net 流——使用流进行文件复制

与Java中的各种文件流,网络流类似,.net中也有各类流.流的主要用途就是与应用程序外部的文件或数据源进行数据交互.基类为Stream,定义在命名空间System.IO下; 一,使用流进行一次性的复制写入 首先我们在桌面上建个测试用的文件,写入些东西: 之后是我们的代码: #region 使用流进行一次性复制 //创建一个文件流对象(参数一:指定了文件的位置:参数二:枚举值,指定操作系统打开文件的方式:参数三:表明了打开文件的意图:注意第二个参数与第三个参数要注意搭配使用) Stream so