POJ 2112 /// 最大流+floyd+二分

题目大意:

有 k台挤奶机 和 c头奶牛

每台挤奶机最多为m头奶牛服务

给定所有挤奶机和奶牛两两之间的距离

求一种分配 使得 奶牛与挤奶机之间的最远距离 最小化

floyd求得所有挤奶机与奶牛两两之间的最短距离

二分一个最远距离M 建图

超级源点s与所有奶牛连容量为1的边

所有挤奶机与超级汇点t连容量为m的边

奶牛与挤奶机之间距离<=M的连容量为1的边

跑s到t的最大流 若最大流为c 说明这个最远距离M是符合要求的

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define mem(i,j) memset(i,j,sizeof(i))
const int N=300;
int d[N][N],L,R;
int n,m,s,t;

/**Dinic*/
struct NODE { int v,w,r; };
vector <NODE> E[N];
void addE(int u,int v,int w) {
    E[u].push_back({v,w,E[v].size()});
    E[v].push_back({u,0,E[u].size()-1});
}
int lev[N], cur[N];
bool bfs(int s,int t) {
    mem(lev,0); lev[s]=1;
    queue <int> q; q.push(s);
    while(!q.empty()) {
        int u=q.front(); q.pop();
        for(int i=0;i<E[u].size();i++) {
            NODE e=E[u][i];
            if(e.w>0 && !lev[e.v]) {
                lev[e.v]=lev[u]+1;
                q.push(e.v);
            }
        }
    }
    return lev[t]>0;
}
int dfs(int s,int t,int f) {
    if(s==t) return f;
    for(int& i=cur[s];i<E[s].size();i++) {
        NODE& e=E[s][i];
        if(e.w>0 && lev[s]<lev[e.v]) {
            int d=dfs(e.v,t,min(f,e.w));
            if(d>0) {
                e.w-=d; E[e.v][e.r].w+=d;
                return d;
            }
        }
    }
    return 0;
}
int maxFlow(int s,int t) {
    int flow=0, f;
    while(bfs(s,t)) {
        mem(cur,0);
        while((f=dfs(s,t,INF))>0) flow+=f;
    }
    return flow;
}
/***/

bool check(int k,int c,int m,int M) {
    for(int i=0;i<=n+1;i++) E[i].clear();
    s=0,t=n+1;
    for(int i=k+1;i<=n;i++) addE(s,i,1);
    for(int i=1;i<=k;i++) addE(i,t,m);
    for(int i=k+1;i<=n;i++)
        for(int j=1;j<=k;j++)
            if(d[i][j]<=M) addE(i,j,1);
    return maxFlow(s,t)==c;
}

void floyd(int k,int c) {
    L=INF, R=-INF;
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) {
                d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
                L=min(L,d[i][j]); R=max(R,d[i][j]);
            }
}

int main()
{
    int k,c,m;
    while(~scanf("%d%d%d",&k,&c,&m)) {
        n=k+c;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) {
                scanf("%d",&d[i][j]);
                if(i!=j && !d[i][j])
                    d[i][j]=INF;
            }
        floyd(k,c);
        int ans=0;
        while(L<=R) {
            int M=(L+R)>>1;
            if(check(k,c,m,M))
                ans=M,R=M-1;
            else L=M+1;
        }
        printf("%d\n",ans);
    }

    return 0;
}

原文地址:https://www.cnblogs.com/zquzjx/p/10663910.html

时间: 2025-01-16 11:20:33

POJ 2112 /// 最大流+floyd+二分的相关文章

poj 2391 Ombrophobic Bovines(最大流+floyd+二分)

Ombrophobic Bovines Time Limit: 1000MSMemory Limit: 65536K Total Submissions: 14519Accepted: 3170 Description FJ's cows really hate getting wet so much that the mere thought of getting caught in the rain makes them shake in their hooves. They have de

POJ 2112 Optimal Milking (二分 + floyd + 网络流)

POJ 2112 Optimal Milking 链接:http://poj.org/problem?id=2112 题意:农场主John 将他的K(1≤K≤30)个挤奶器运到牧场,在那里有C(1≤C≤200)头奶牛,在奶牛和挤奶器之间有一组不同长度的路.K个挤奶器的位置用1-K的编号标明,奶牛的位置用K+1-K+C 的编号标明.每台挤奶器每天最多能为M(1≤M≤15)头奶牛挤奶.寻找一个方案,安排每头奶牛到某个挤奶器挤奶,并使得C 头奶牛需要走的所有路程中的最大路程最小.每个测试数据中至少有一

POJ 2112 Optimal Milking(二分+最大流)

POJ 2112 Optimal Milking 题目链接 题意:给定一些机器和奶牛,在给定距离矩阵,(不在对角线上为0的值代表不可达),每个机器能容纳m个奶牛,问所有奶牛都能挤上奶,那么走的距离最大的奶牛的最小值是多少 思路:明显的二分+最大流,注意floyd求出的距离矩阵最大值可能不止200,所以二分的上限要注意 代码: #include <cstdio> #include <cstring> #include <queue> #include <algori

POJ 2112 最大流+二分+(建图:最重要的)

Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12521   Accepted: 4524 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) co

POJ 2391-Ombrophobic Bovines(网络流_最大流+floyd+二分)

Ombrophobic Bovines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15485   Accepted: 3361 Description FJ's cows really hate getting wet so much that the mere thought of getting caught in the rain makes them shake in their hooves. They h

POJ 2112-Optimal Milking(网络流_最大流+floyd+二分查找)

Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12810   Accepted: 4632 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) co

POJ 2112: Optimal Milking【二分,网络流】

题目大意:K台挤奶机,C个奶牛,每台挤奶器可以供M头牛使用,给出奶牛和和机器间的距离矩阵,求所有奶牛走最大距离的最小值 思路:最大距离的最小值,明显提示二分,将最小距离二分之后问题转化成为:K台挤奶机,C个奶牛,每台挤奶器可以供M头牛使用,已知每头牛可以到的挤奶机是哪些,问能否让所有奶牛挤上奶. 这个问题就是典型的二分图多重匹配问题,跑个网络流看是否满流即可,最后才发现给出的矩阵不一定是最短路径TUT 所以要跑一遍floyd #include<iostream> #include<cst

POJ 2112【最短路+二分+网络流】

题目描述:(转)k个机器,每个机器最多服务m头牛.c头牛,每个牛需要1台机器来服务.告诉你牛与机器每个之间的直接距离.问:让所有的牛都被服务的情况下,使走的最远的牛的距离最短,求这个距离. #include<stdio.h> #include<string.h> #include<queue> #define maxn 1000 #define INF 0x3f3f3f3f using namespace std; int k, m, c; struct e { int

POJ 2112 Optimal Milking 最优挤奶方案 Floyd算法+二分查找+最大流

题目链接:POJ 2112 Optimal Milking Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12446   Accepted: 4494 Case Time Limit: 1000MS Description FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among