[bzoj1738]发抖的牛
二分答案,每一头牛向所有在规定时间内能走到的牛棚连inf的边,每一个源点向牛连牛数量的边,每一个牛棚向汇点连牛棚容量的边,能满流则意味着这个答案可行,否则不可行。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 505 4 #define ll long long 5 #define inf 0x3f3f3f3f 6 struct ji{ 7 int nex,to,len; 8 }e[N*N],edge[N*N]; 9 queue<int>q; 10 int E,EE,n,m,x,y,z,s,a[N],d[N],head[N],work[N]; 11 ll f[N][N]; 12 void add(int x,int y,int z){ 13 edge[E].nex=head[x]; 14 edge[E].to=y; 15 edge[E].len=z; 16 head[x]=E++; 17 if (E&1)add(y,x,0); 18 } 19 bool bfs(){ 20 q.push(0); 21 memset(d,-1,sizeof(d)); 22 d[0]=0; 23 while (!q.empty()){ 24 int k=q.front(); 25 q.pop(); 26 for(int i=head[k];i!=-1;i=edge[i].nex) 27 if ((edge[i].len)&&(d[edge[i].to]<0)){ 28 d[edge[i].to]=d[k]+1; 29 q.push(edge[i].to); 30 } 31 } 32 return d[n]>=0; 33 } 34 int dfs(int k,int s){ 35 if (k==n)return s; 36 int p; 37 for(int &i=work[k];i!=-1;i=edge[i].nex) 38 if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){ 39 p=dfs(edge[i].to,min(s,edge[i].len)); 40 if (p){ 41 edge[i].len-=p; 42 edge[i^1].len+=p; 43 return p; 44 } 45 } 46 return 0; 47 } 48 int dinic(){ 49 int k,ans=0; 50 while (bfs()){ 51 memcpy(work,head,sizeof(work)); 52 while (k=dfs(0,inf))ans+=k; 53 } 54 return ans; 55 } 56 bool pd(ll k){ 57 for(int i=1;i<=n/2;i++) 58 for(int j=1;j<=n/2;j++) 59 if (f[i][j]<=k)add(i,j+n/2,inf); 60 int t=dinic(); 61 memcpy(head,a,sizeof(a)); 62 memcpy(edge,e,sizeof(e)); 63 E=EE; 64 return t==s; 65 } 66 int main(){ 67 scanf("%d%d",&n,&m); 68 memset(head,-1,sizeof(head)); 69 for(int i=1;i<=n;i++){ 70 scanf("%d%d",&x,&y); 71 add(0,i,y); 72 add(n+i,2*n+1,x); 73 s+=x; 74 } 75 memset(f,inf,sizeof(f)); 76 for(int i=1;i<=n;i++)f[i][i]=0; 77 for(int i=1;i<=m;i++){ 78 scanf("%d%d%d",&x,&y,&z); 79 f[x][y]=f[y][x]=min(f[x][y],1LL*z); 80 } 81 for(int i=1;i<=n;i++) 82 for(int j=1;j<=n;j++) 83 for(int k=1;k<=n;k++) 84 f[j][k]=min(f[j][k],f[j][i]+f[i][k]); 85 n=n*2+1; 86 ll l=0,r=2e11; 87 memcpy(a,head,sizeof(a)); 88 memcpy(e,edge,sizeof(e)); 89 EE=E; 90 while (l<r){ 91 ll mid=(l+r>>1); 92 if (pd(mid))r=mid; 93 else l=mid+1; 94 } 95 if (l==2e11)l=-1; 96 printf("%lld",l); 97 }