Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 12936 | Accepted: 4679 | |
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
题意:K个挤奶器,C头牛,每个挤奶器最多能挤M头牛的奶,如何分配使得所有牛都被挤一次奶,并且使得这些牛到挤奶器所走路程中最长的最小化。
此题和poj2391类似,都是二分距离,然后最大流。
首先预处理各点之间的最短路,然后源点连向所有牛一条边,边权为1,所有挤奶器连向汇点,边权为M,对于二分的距离,若牛i与挤奶器j的最短路<=该距离,则加一条边(i,j),边权为1.
代码:
#include<cstdio> #include<iostream> #include<cstring> #define Maxn 250 using namespace std; int K,C,M; int dist[Maxn][Maxn]; void floyd(){ for(int k=1;k<=K+C;k++) for(int i=1;i<=K+C;i++) for(int j=1;j<=K+C;j++) dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]); } const int inf=0x3f3f3f3f; struct line{ int to,next,cap; }p[Maxn*Maxn*2]; int head[Maxn]; int q[Maxn]; int d[Maxn]; int tot; int src,t; int n,m; void addedge(int a,int b,int c){ p[tot].to=b; p[tot].next=head[a]; p[tot].cap=c; head[a]=tot++; } void insert(int a,int b,int c){ addedge(a,b,c); addedge(b,a,0); } bool bfs(){ memset(d,-1,sizeof d); int s=0,e=-1; q[++e]=src; d[src]=0; while(s<=e){ int u=q[s++]; for(int i=head[u];i!=-1;i=p[i].next){ int v=p[i].to; if(d[v]==-1&&p[i].cap){ d[v]=d[u]+1; q[++e]=v; } } } return d[t]!=-1; } int dfs(int u,int alpha){ if(u==t) return alpha; int w,used=0; for(int i=head[u];i!=-1&&used<alpha;i=p[i].next){ int v=p[i].to; if(p[i].cap&&d[v]==d[u]+1){ w=dfs(v,min(alpha-used,p[i].cap)); used+=w; p[i].cap-=w; p[i^1].cap+=w; } } if(!used) d[u]=-1; return used; } int dinic(){ int ans=0; src=0,t=K+C+1; while(bfs()) ans+=dfs(src,inf); return ans; } void add(int mid){ memset(head,-1,sizeof head); tot=0; for(int i=1;i<=C;i++) insert(0,K+i,1); for(int i=K+1;i<=K+C;i++) for(int j=1;j<=K;j++) if(dist[i][j]<=mid) insert(i,j,1); for(int i=1;i<=K;i++) insert(i,K+C+1,M); } int main() { while(cin>>K>>C>>M){ for(int i=1;i<=K+C;i++) for(int j=1;j<=K+C;j++){ scanf("%d",&dist[i][j]); if(i!=j&&!dist[i][j]) dist[i][j]=inf; } floyd(); int l=0,r=inf; while(l<r){ int mid=l+r>>1; add(mid); if(dinic()<C) l=mid+1; else r=mid; } printf("%d\n",l); } return 0; }