POJ-2112 Optimal Milking
阿新 • • 發佈:2018-11-02
floyd+網路流+二分
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; typedef long long ll; const int N=300+10; const int M=2e4+10; const int INF=0x7f7f7f7f; struct Edge { int to,nxt,cap,flow; }edge[M]; int tot,first[N]; void addedge(int u,int v,int w,int rw=0) { edge[tot].to=v;edge[tot].cap=w;edge[tot].flow=0; edge[tot].nxt=first[u];first[u]=tot++; edge[tot].to=u;edge[tot].cap=rw;edge[tot].flow=0; edge[tot].nxt=first[v];first[v]=tot++; } void init() { tot=0; memset(first,-1,sizeof(first)); } int gap[N],dep[N],cur[N]; int Q[N],S[N]; void bfs(int s) { memset(gap,0,sizeof(gap)); memset(dep,-1,sizeof(dep)); int q0=0,q1=0; Q[q1++]=s; dep[s]=0; gap[0]=1; while(q0<q1) { int u=Q[q0++]; for(int i=first[u];i!=-1;i=edge[i].nxt) { int v=edge[i].to; if(dep[v]!=-1) continue; Q[q1++]=v; dep[v]=dep[u]+1; gap[dep[v]]++; } } } int sap(int s,int t,int n) { int ans=0; bfs(t); memcpy(cur,first,sizeof(first)); int top=0; int u=s; while(dep[s]<n) { if(u==t) { int Min=INF; int inser; for(int i=0;i<top;i++) if(Min>edge[S[i]].cap-edge[S[i]].flow) { Min=edge[S[i]].cap-edge[S[i]].flow; inser=i; } for(int i=0;i<top;i++) { edge[S[i]].flow+=Min; edge[S[i]^1].flow-=Min; } ans+=Min; top=inser; u=edge[S[top]^1].to; } bool flag=false; int v; for(int i=cur[u];i!=-1;i=edge[i].nxt) { v=edge[i].to; if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u]) { flag=true; cur[u]=S[top++]=i; break; } } if(flag) { u=v; continue; } gap[dep[u]]--; if(!gap[dep[u]]) return ans; int Min=n; for(int i=first[u];i!=-1;i=edge[i].nxt) if(edge[i].cap-edge[i].flow&&Min>dep[edge[i].to]) { Min=dep[edge[i].to]; cur[u]=i; } dep[u]=Min+1; gap[dep[u]]++; if(u!=s) u=edge[S[--top]^1].to; } return ans; } int g[N][N]; int main() { int k,c,m; while(~scanf("%d%d%d",&k,&c,&m)) { int n=k+c; int s=n,t=n+1; for(int i=0;i<n;i++) for(int j=0;j<n;j++) { scanf("%d",&g[i][j]); if(!g[i][j]) g[i][j]=60000; } for(int p=0;p<n;p++) { for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(i==j) continue; g[i][j]=min(g[i][j],g[i][p]+g[p][j]); } } int ans=60000,l=1,r=60000; while(l<=r) { int mid=(l+r)>>1; init(); for(int i=0;i<k;i++) addedge(s,i,m); for(int i=k;i<n;i++) addedge(i,t,1); for(int i=0;i<k;i++) for(int j=k;j<n;j++) if(g[i][j]<=mid) addedge(i,j,1); int num=sap(s,t,t+1); if(num<c) { l=mid+1; } else { ans=mid; r=mid-1; } } printf("%d\n",ans); } return 0; }