为 二分加网络流 二分答案即可
图很好建 注意double型二分的写法。。一开始 1 加 fabs 2 L+一个值 R-一遍
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define ll long long #define pb push_back #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 0x3f3f3f3f const int N=1e4+44; const int M=1e4+54; double eps=1e-4; int d[N]; struct edge { int to, next;double w; } e[M << 1]; int head[N],cur[N],cnt = 1; void add(int x, int y, double z) { e[++cnt] = (edge){y, head[x], z}; head[x] = cnt; e[++cnt] = (edge){x, head[y], 0}; head[y] = cnt; } void init() { rep(i,0,cnt)head[i]=0; cnt=1; } int level[N]; bool bfs(int s, int t) { memset(level, 0, sizeof level); queue<int> q; level[s] = 1; q.push(s); while (!q.empty()) { int pos = q.front();q.pop(); for (int i = head[pos]; i; i = e[i].next) { int nx = e[i].to; if (!e[i].w || level[nx]) continue; level[nx] = level[pos] + 1; q.push(nx); } } return level[t]; } double dfs(int s, int t, double flow) { if(s==t||flow==0)return flow; double f,ret = 0; for (int &i = cur[s],v; i; i = e[i].next) { v = e[i].to; if (level[v] == level[s] + 1 && (f=dfs(v,t,min(flow,e[i].w)))>0) { e[i].w -= f; e[i ^ 1].w += f; flow -= f; ret += f; if(!flow)break; } } return ret; } double dinic(int s, int t) { double ret = 0.0; while (bfs(s, t)) memcpy(cur,head,sizeof cur),ret += dfs(s, t, inf); return ret; } int n,m,s,t,a,b,c,S,T; int hp[N],attack[N],sum,mp[100][100]; bool check(double mid) { init(); rep(i,1,n)add(i,t,1.0*hp[i]); rep(i,1,m) { add(s,i+n,1.0*mid*attack[i]); rep(j,1,n) { if(mp[i][j]) add(i+n,j,1.0*inf); } } double ans=dinic(s,t); return fabs(ans-1.0*sum)<=eps; } int main() { scanf("%d%d",&n,&m);s=n+m+1,t=s+1; rep(i,1,n)scanf("%d",&hp[i]),sum+=hp[i]; rep(i,1,m)scanf("%d",&attack[i]); rep(i,1,m)rep(j,1,n)scanf("%d",&mp[i][j]); double L=0,R=1000000,ans=0; while(R-L>=0.001) { double mid=(L+R)/2; if(check(mid))R=mid,ans=mid; else L=mid; } printf("%.6f",ans); return 0; }