标签:
| Time Limit: 2000MS | Memory Limit: 30000K | |
| Total Submissions: 13897 | Accepted: 5018 | |
| Case Time Limit: 1000MS | ||
Description
Input
Output
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
上面图片有详细的题意和解析,来自图论算法理论,实现及应用这本书。
先用floyd求解任意两点之间的最短距离,再构建网络,将牛与源点相连容量为1(则从原点出去的中流量为C),将挤奶器与汇点相连容量为m。然后用dinic算法求最大流,二分枚举答案,将牛与挤奶器之间的距离小于枚举值得边 加入网络,大于枚举值得边去掉。找到可以使汇点的流入量为C的且符合条件的最小值就是答案。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define maxn 1100
#define maxm 550000
#define INF 1000000
using namespace std;
int dist[maxn], vis[maxn];
int head[maxn], cur[maxn], cnt;
int map[maxn][maxn];
struct node{
int u, v, cap, flow, next;
};
node edge[maxm];
int K, C, M, n;
void init(){
cnt = 0;
memset(head, -1, sizeof(head));
}
void add(int u, int v, int w){
edge[cnt] = {u, v, w, 0, head[u]};
head[u] = cnt++;
edge[cnt] = {v, u, 0, 0, head[v]};
head[v] = cnt++;
}
void getmap(int min_max){
int i, j;
for(i = K + 1; i <= n; ++i)
add(0, i, 1);
for(i = 1; i <= K; ++i)
add(i, n + 1, M);
for(i = K + 1; i <= n; ++i)
for(j = 1; j <= K; ++j)
if(map[i][j] <= min_max) add(i, j, 1);
}
bool BFS(int st, int ed){
queue<int>q;
memset(vis, 0, sizeof(vis));
memset(dist, -1, sizeof(dist));
q.push(st);
vis[st] = 1;
dist[st] = 0;
while(!q.empty()){
int u = q.front();
q.pop();
for(int i = head[u]; i != -1; i = edge[i].next){
node E = edge[i];
if(!vis[E.v] && E.cap > E.flow){
vis[E.v] = 1;
dist[E.v] = dist[u] + 1;
if(E.v == ed) return true;
q.push(E.v);
}
}
}
return false;
}
int DFS(int x, int ed, int a){
if(a == 0 || x == ed)
return a;
int flow = 0, f;
for(int &i = cur[x]; i != -1; i =edge[i].next){
node &E = edge[i];
if(dist[E.v] == dist[x] + 1 && (f = DFS(E.v, ed, min(a, E.cap - E.flow))) > 0){
E.flow += f;
edge[i ^ 1].flow -= f;
flow += f;
a -= f;
if(a == 0) break;
}
}
return flow;
}
int maxflow (int st, int ed){
int flowsum = 0;
while(BFS(st, ed)){
memcpy(cur, head, sizeof(head));
flowsum += DFS(st, ed, INF);
}
return flowsum;
}
int main (){
while(scanf("%d%d%d", &K,&C,&M) != EOF){
n = C + K;
int i, j , k;
for(i = 1; i <= n; ++i)
for(j = 1; j <= n; ++j){
scanf("%d", &map[i][j]);
if(map[i][j] == 0) map[i][j] = INF;
}
for(k = 1; k <= n; ++k)
for(i = 1; i <= n; ++i)
if(map[i][k] != INF){
for(j = 1; j <= n; ++j)
map[i][j] = min(map[i][k] + map[k][j], map[i][j]);
}
int L = 0, R = 60000, mid, ans;
while( R > L){
mid = (L + R) / 2;
ans = 0;
init();
getmap(mid);
ans = maxflow(0, n + 1);
if(ans >= C) R = mid;
else L = mid + 1;
}
printf("%d\n", R);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ 2112--Optimal Milking【二分找最大距离的最小值 && 最大流】
标签:
原文地址:http://blog.csdn.net/hpuhjh/article/details/47300911