poj 2112 网络流
2013-04-14 19:37
357 查看
题意:有K台挤奶机(编号1~K),C头奶牛(编号K+1~K+C),给出各点之间距离。现在要让C头奶牛到挤奶机去挤奶,每台挤奶机只能处理M头奶牛,求使所走路程最远的奶牛的路程最短的方案。
构图:先Floyd求所有点对之间最短路,二分最短长度,若奶牛与挤奶机之间的距离大于mid则不连边,否则连容量为1的边。源向奶牛连容量1的边,机器向汇连容量m的边,用最大流判可行性。
#include <iostream>
#include<stdio.h>
#include<string.h>
const int maxn=1001;
const int inf=1<<30;
using namespace std;
int a[maxn][maxn],e[maxn][maxn];
int floyd(int n)
{
for(int
k=1;k<=n;k++)
for(int
i=1;i<=n;i++)
for(int
j=1;j<=n;j++)
if(a[i][k]&&a[k][j]&&a[i][k]+a[k][j]<a[i][j])
a[i][j]=a[i][k]+a[k][j];
else
if(a[i][k]&&a[k][j]&&a[i][j]==0)
a[i][j]=a[i][k]+a[k][j];
}
int level[maxn];
int makelevel(int s,int t)
{
memset(level,0,sizeof(level));
int
que[maxn];
level[s]=1;
int
top=0;
que[++top]=s;
for(int
i=1;i<=top;i++)
{
int u=que[i];
if(u==t) return(1);
for(int k=1;k<=t;k++)
if(!level[k]&&e[u][k])
{
que[++top]=k;
level[k]=level[u]+1;
}
}
return(0);
}
int dfs(int now,int maxf,int t)
{
if(now==t)
return(maxf);
int
ret=0;
for(int
k=1;k<=t;k++)
if(e[now][k]&&level[k]==level[now]+1)
{
int f=dfs(k,min(maxf-ret,e[now][k]),t);
e[now][k]-=f;
e[k][now]+=f;
ret+=f;
if(ret==maxf) return(ret);
}
return(ret);
}
int dinic(int s,int t)
{
int
ans=0;
while(makelevel(s,t)) ans+=dfs(s,inf,t);
return(ans);
}
int main()
{
int
k,c,m;
scanf("%d %d
%d",&k,&c,&m);
int
n=k+c;
memset(a,0,sizeof(a));
for(int
i=1;i<=n;i++)
for(int
j=1;j<=n;j++)
scanf("%d",&a[i][j]);
floyd(n);
int
sm=1,bg=0,mid;
for(int
i=1;i<=n;i++)
for(int
j=1;j<=n;j++)
if(a[i][j]>bg) bg=a[i][j];
mid=(sm+bg)/2;
while(sm!=bg)
{
memset(e,0,sizeof(e));
for(int i=1;i<=k;i++)
e[i][c+k+2]=m;
for(int i=k+1;i<=k+c;i++)
e[c+k+1][i]=1;
for(int i=k+1;i<=n;i++)
for(int j=1;j<=k;j++)
if(a[i][j]<=mid&&a[i][j])
e[i][j]=1;
if(dinic(c+k+1,c+k+2)==c)
{
bg=mid;
mid=(sm+bg)/2;
}
else
{
sm=mid+1;
mid=(sm+bg)/2;
}
//
printf("%d %d\n",sm,bg);
}
printf("%d\n",sm);
return
0;
}
构图:先Floyd求所有点对之间最短路,二分最短长度,若奶牛与挤奶机之间的距离大于mid则不连边,否则连容量为1的边。源向奶牛连容量1的边,机器向汇连容量m的边,用最大流判可行性。
#include <iostream>
#include<stdio.h>
#include<string.h>
const int maxn=1001;
const int inf=1<<30;
using namespace std;
int a[maxn][maxn],e[maxn][maxn];
int floyd(int n)
{
for(int
k=1;k<=n;k++)
for(int
i=1;i<=n;i++)
for(int
j=1;j<=n;j++)
if(a[i][k]&&a[k][j]&&a[i][k]+a[k][j]<a[i][j])
a[i][j]=a[i][k]+a[k][j];
else
if(a[i][k]&&a[k][j]&&a[i][j]==0)
a[i][j]=a[i][k]+a[k][j];
}
int level[maxn];
int makelevel(int s,int t)
{
memset(level,0,sizeof(level));
int
que[maxn];
level[s]=1;
int
top=0;
que[++top]=s;
for(int
i=1;i<=top;i++)
{
int u=que[i];
if(u==t) return(1);
for(int k=1;k<=t;k++)
if(!level[k]&&e[u][k])
{
que[++top]=k;
level[k]=level[u]+1;
}
}
return(0);
}
int dfs(int now,int maxf,int t)
{
if(now==t)
return(maxf);
int
ret=0;
for(int
k=1;k<=t;k++)
if(e[now][k]&&level[k]==level[now]+1)
{
int f=dfs(k,min(maxf-ret,e[now][k]),t);
e[now][k]-=f;
e[k][now]+=f;
ret+=f;
if(ret==maxf) return(ret);
}
return(ret);
}
int dinic(int s,int t)
{
int
ans=0;
while(makelevel(s,t)) ans+=dfs(s,inf,t);
return(ans);
}
int main()
{
int
k,c,m;
scanf("%d %d
%d",&k,&c,&m);
int
n=k+c;
memset(a,0,sizeof(a));
for(int
i=1;i<=n;i++)
for(int
j=1;j<=n;j++)
scanf("%d",&a[i][j]);
floyd(n);
int
sm=1,bg=0,mid;
for(int
i=1;i<=n;i++)
for(int
j=1;j<=n;j++)
if(a[i][j]>bg) bg=a[i][j];
mid=(sm+bg)/2;
while(sm!=bg)
{
memset(e,0,sizeof(e));
for(int i=1;i<=k;i++)
e[i][c+k+2]=m;
for(int i=k+1;i<=k+c;i++)
e[c+k+1][i]=1;
for(int i=k+1;i<=n;i++)
for(int j=1;j<=k;j++)
if(a[i][j]<=mid&&a[i][j])
e[i][j]=1;
if(dinic(c+k+1,c+k+2)==c)
{
bg=mid;
mid=(sm+bg)/2;
}
else
{
sm=mid+1;
mid=(sm+bg)/2;
}
//
printf("%d %d\n",sm,bg);
}
printf("%d\n",sm);
return
0;
}
相关文章推荐
- poj 2112 中等网络流
- poj&nbsp;2112&nbsp;Optimal&nbsp;Milking(floyd+…
- poj 1789 Truck History
- poj 1905
- poj 1273 && hdu 1532 Drainage Ditches (网络最大流)
- poj 3628_0/1背包
- poj 2942 LA3523 点-双…
- poj 3352
- poj 2449 求第k最短路 A* + SPFA
- poj 3207 简单的2-SAT问题
- POJ&nbsp;3006
- POJ&nbsp;1799
- POJ&nbsp;2136
- 网络子系统5_设备队列规则&nbsp;.
- POJ 2262 Goldbach's Conjecture(…
- POJ 1658 Eva's Problem(水到极点)
- poj 1276 Cash Machine
- poj 3667 Hotel
- poj 1436 Horizontally&…
- 【安卓开机动画】火爆网络 Su…