Question address: http://poj.org/problem? Id = 2112
Recently, I was busy preparing for the textbook, but I didn't have much questions. (I was really reading a book ..) If you don't need to answer questions, you still need to itch your hands and immediately invite the competition. you should brush your questions before going to bed every night. The daytime is enough.
This question has been adjusted for one night... I always thought it was a few days without a knock .. (Though not several days ..) When an error was found, it was found that there were fewer letters... In addition, I rarely encounter errors in the BFS, and the errors are hidden .. So after one night, I typed a wrong letter to hate it.
This question is probably the longest algorithm question in my career so far .. (Except for simulated questions ..) It uses two points (maximum distance of two points) to find the shortest path (the shortest distance between the machine and the ox) and the network stream ISAP (to determine whether the stream is full, full stream indicates that all cows can eat food at this time ).
The idea of creating a map is to establish a super source point and a super sink point, connect the machine with the super source point, and set the weight to the maximum supply of each machine, and connect the ox with the super sink point, the weight is 1. If the shortest distance between the ox and the machine is less than or equal to the maximum distance of the second to the second, the edge is connected. The weight is 1. Then, determine whether the stream is full. The maximum stream is required for every two minutes and whether the stream is full or not. The final minimum value is the required answer.
The Code is as follows:
#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#include <ctype.h>#include <queue>#include <map>#include <algorithm>using namespace std;int dp[300][300], head[300], s, t, nv, maxint=99999999, cnt, n, c;int num[300], d[300], pre[300], q[300], cur[300];struct node{ int u, v, cap; int next;}edge[1000000];void add(int u, int v, int cap){ edge[cnt].v=v; edge[cnt].cap=cap; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].v=u; edge[cnt].cap=0; edge[cnt].next=head[v]; head[v]=cnt++;}void floyd(){ int i, j, k; for(k=1;k<=n;k++) { for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(dp[i][j]>dp[i][k]+dp[k][j]) { dp[i][j]=dp[i][k]+dp[k][j]; } } } }}void bfs(){ memset(num,0,sizeof(num)); memset(d,-1,sizeof(d)); int f1=0, f2=0, i; d[t]=0; num[0]=1; q[f1++]=t; while(f1>=f2) { int u=q[f2++]; for(i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(d[v]==-1) { d[v]=d[u]+1; num[d[v]]++; q[f1++]=v; } } }}int isap(){ memcpy(cur,head,sizeof(cur)); bfs(); int flow=0, u=pre[s]=s, i; while(d[s]<nv) { if(u==t) { int f=maxint, pos; for(i=s;i!=t;i=edge[cur[i]].v) { if(f>edge[cur[i]].cap) { f=edge[cur[i]].cap; pos=i; } } for(i=s;i!=t;i=edge[cur[i]].v) { edge[cur[i]].cap-=f; edge[cur[i]^1].cap+=f; } flow+=f; if(flow>c) return flow; u=pos; } for(i=cur[u];i!=-1;i=edge[i].next) { if(d[edge[i].v]+1==d[u]&&edge[i].cap) { break; } } if(i!=-1) { cur[u]=i; pre[edge[i].v]=u; u=edge[i].v; } else { if(--num[d[u]]==0) break; int mind=nv; for(i=head[u];i!=-1;i=edge[i].next) { if(mind>d[edge[i].v]&&edge[i].cap) { mind=d[edge[i].v]; cur[u]=i; } } d[u]=mind+1; num[d[u]]++; u=pre[u]; } } return flow;}int main(){ int k, m, i, j, x, ans; while(scanf("%d%d%d",&k,&c,&m)!=EOF) { n=k+c; for(i=1;i<=k+c;i++) { for(j=1;j<=k+c;j++) { scanf("%d",&dp[i][j]); if(dp[i][j]==0) dp[i][j]=maxint; } } floyd(); /*for(i=1;i<=k;i++) { for(j=1;j<=c;j++) { printf("%d ",dp[i][j+k]); } printf("\n"); }*/ int high=400000, mid, low=1; while(low<=high) { mid=(high+low)/2; s=0; t=n+1; nv=t+1; memset(head,-1,sizeof(head)); cnt=0; for(i=1;i<=k;i++) { add(s,i,m); } for(i=1;i<=c;i++) { add(k+i,t,1); } for(i=1;i<=k;i++) { for(j=1;j<=c;j++) { if(dp[i][k+j]<=mid) { add(i,k+j,1); } } } x=isap(); //printf("%d\n",x); //return 0; if(x>=c) { ans=mid; high=mid-1; } else if(x<c) { low=mid+1; } } printf("%d\n",ans); } return 0;}