Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 15074 | Accepted: 5386 | |
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
Source
设一个S点和一个T点,由S点向每一个奶牛点连容量为1的边,由每个挤奶机点向T点连容量为M的边,再由每个奶牛点向它能到达的挤奶机连容量为1的边,边权为这头奶牛到这个机器的最短路(floyd预处理)。
然后二分枚举允许奶牛走的最长的路程,假设这个最长的路程为mid。并把网络流途中边权大于mid的边都删去,跑一遍最大流,如果最大流等于C,就说明所有奶牛走的路程都小于等于mid的情况下,所有奶牛都能到达挤奶机。反之,如果最大流小于C,说明所有的奶牛走的路程都小于等于mid的情况下,有些奶牛无法分配到挤奶机挤奶。
15152009 | 710395641 | 2112 | Accepted | 3132K | 188MS | G++ | 2162B | 2016-02-10 19:38:38 |
//poj2112 Optimal Milking 二分+最大流 #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define maxn 500 #define inf 0x3f3f3f3f #define S N+K+1 #define T N+K+2 using namespace std; int N, K, M, cost[maxn][maxn], head[maxn], next[maxn*maxn], c[maxn*maxn], to[maxn*maxn], tot=1, mid, f[maxn*maxn], tot_flow, deep[maxn]; queue<int> q; void add(int a, int b, int v) { to[++tot]=b;c[tot]=v; next[tot]=head[a];head[a]=tot; if(~tot&1)add(b,a,0); } void input() { int i, j; for(i=1;i<=N+K;i++) for(j=1;j<=N+K;j++) { scanf("%d",&cost[i][j]); if(cost[i][j]==0&&i!=j)cost[i][j]=inf; } } void floyd() { int i, j, k; for(k=1;k<=N+K;k++) for(i=1;i<=N+K;i++) for(j=1;j<=N+K;j++) if(cost[i][j]>cost[i][k]+cost[k][j]) cost[i][j]=cost[i][k]+cost[j][k]; } void setmap() { int i, j; memset(head,0,sizeof(head));tot=1; memset(next,0,sizeof(next)); for(i=1;i<=N;i++)add(S,K+i,1); for(i=1;i<=K;i++)add(i,T,M); for(i=1;i<=N;i++)for(j=1;j<=K;j++) if(cost[K+i][j]<=mid)add(K+i,j,cost[K+i][j]); } bool BFS() { int p, x; memset(deep,-1,sizeof(deep)); q.push(S);deep[S]=0; while(!q.empty()) { x=q.front();q.pop(); for(p=head[x];p;p=next[p]) if(deep[ to[p] ]==-1 && c[p]-f[p]) deep[to[p]]=deep[x]+1,q.push(to[p]); } return deep[T]!=-1; } int dfs(const int x, const int flow) { int p, t; if(x==T)return flow; for(p=head[x];p;p=next[p]) if( deep[to[p]]==deep[x]+1 && c[p]-f[p] && (t=dfs(to[p],min(flow,c[p]-f[p]))) ) {f[p]+=t,f[p^1]-=t;return t;} return 0; } bool check() { int i, j, t; setmap(); tot_flow=0; memset(f,0,sizeof(f)); while(BFS()) while(t=dfs(S,0x7fffffff))tot_flow+=t; return tot_flow==N; } int main() { int i, j, maxx, l, r; while(scanf("%d%d%d",&K,&N,&M)!=EOF) { input(); floyd(); maxx=-inf; for(i=1;i<=N+K;i++) for(j=1;j<=N+K;j++) maxx=max(maxx,cost[i][j]); l=1,r=maxx,mid=(l+r)>>1; while(l<r) { if(check())r=mid; else l=mid+1; mid=(l+r)>>1; } printf("%d\n",r); } return 0; }