您的位置:首页 > 其它

[最大流]poj 2112 ptimal Milking#floyd+二分+最大流

2012-08-26 19:49 309 查看
/**
[最大流]poj 2112 ptimal Milking#floyd+二分+最大流
关键还是最大流,二分最大距离
源点到牛的边为1,牛到可达的机器建边权为1,机器到汇点建边权为m,
满足条件为最大流为c
*/
#include <stdio.h>
#include <string.h>

#define N 256
#define INF 500000
int k,c,m,d

,s = 0,t;

typedef int typec;
#define E 1100001
// type of cost
const int inf = 10000000;
// max of cost
struct edge { int x, y, nxt; typec c; } bf[E];
int ne, head[E], cur[E], ps[E], dep[E];
void addedge(int x, int y, typec c)
{
// add an arc(x -> y, c); vertex: 0 ~ n-1;
bf[ne].x = x; bf[ne].y = y; bf[ne].c = c;
bf[ne].nxt = head[x]; head[x] = ne++;
bf[ne].x = y; bf[ne].y = x; bf[ne].c = 0;
bf[ne].nxt = head[y]; head[y] = ne++;
}
typec flow(int n, int s, int t)
{
typec tr, res = 0;
int i, j, k, f, r, top;
while (1) {
memset(dep, -1, n * sizeof(int));
for (f = dep[ps[0] = s] = 0, r = 1; f != r; )
for (i = ps[f++], j = head[i]; j; j = bf[j].nxt)
if(bf[j].c && -1 == dep[k = bf[j].y]){
dep[k] = dep[i] + 1;ps[r++] = k;
if(k == t)
{
f = r;
break;
}
}
if(-1 == dep[t])
break;

memcpy(cur,head,n * sizeof(int));
for(i = s,top = 0;;){
if(i == t){
for(k = 0,tr = inf; k < top; ++k)
if(bf[ps[k]].c < tr)
tr = bf[ps[f = k]].c;
for(k = 0; k < top; ++k)
bf[ps[k]].c -= tr,bf[ps[k]^1].c += tr;
res += tr;
i = bf[ps[top = f]].x;
}
for(j = cur[i]; cur[i]; j = cur[i] = bf[cur[i]].nxt)
if(bf[j].c && dep[i] + 1 == dep[bf[j].y])
break;
if(cur[i]){
ps[top++] = cur[i];
i = bf[cur[i]].y;
}
else{
if(0 == top)
break;
dep[i] = -1;
i = bf[ps[--top]].x;
}
}
}
return res;
}

bool check(int dd)
{
memset(head,0,sizeof(head));
ne = 2;
int i,j;
for(i = k + 1; i < t; ++i)
{
for(j = 1; j <= k; ++j)
if(d[i][j] <= dd)
addedge(i,j,1);
addedge(s,i,1);
}
for(i = 1; i <= k; ++i)
addedge(i,t,m);
return flow(t+1,s,t) >= c;
}
int solve()
{
int l = 1,r = INF,mid;
while(l < r)
{
mid = (l + r) >> 1;
if(check(mid))
r = mid;
else
l = mid + 1;
}
return l;
}
int main()
{
freopen("1.in","r",stdin);
int i,j,kk;
scanf("%d%d%d",&k,&c,&m);
t = k + c + 1;
for(i = 1; i < t; ++i)
for(j = 1; j < t; ++j)
{
scanf("%d",&d[i][j]);
if(d[i][j] == 0)
d[i][j] = inf;
}

for(kk = 1; kk < t; ++kk)
for(i = 1; i < t; ++i)
for(j = 1; j < t; ++j)
if(d[i][j] > d[i][kk] + d[kk][j])
d[i][j] = d[i][kk] + d[kk][j];

printf("%d\n",solve());
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: