luogu3305/bzoj3130 费用流 (二分答案+dinic)
Bob肯定想挑一个流量最大的边,然后把所有的费用都加给它呗
那Alice就让流量最大的边尽量小呗
那就二分一下答案再dinic呗
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=110,maxm=2010; 7 const double inf=1e9; 8 9 inline ll rd(){ 10 ll x=0;char c=getchar();int neg=1; 11 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 12 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 13 return x*neg; 14 } 15 16 struct Edge{ 17 int a,b,ne; 18 double l; 19 }eg[maxm]; 20 int egh[maxn],ect=1; 21 double oril[maxm]; 22 int N,M,P,S,T; 23 int dep[maxn],cur[maxn]; 24 double maxl; 25 queue<int> q; 26 27 inline void adeg(int a,int b,int c){ 28 eg[++ect].a=a,eg[ect].b=b;oril[ect]=eg[ect].l=c,eg[ect].ne=egh[a];egh[a]=ect; 29 eg[++ect].a=b,eg[ect].b=a;oril[ect]=eg[ect].l=0,eg[ect].ne=egh[b];egh[b]=ect; 30 } 31 32 inline bool bfs(){ 33 CLR(dep,0);CLR(cur,-1); 34 dep[S]=1;q.push(S); 35 while(!q.empty()){ 36 int p=q.front();q.pop(); 37 for(int i=egh[p];i;i=eg[i].ne){ 38 int b=eg[i].b; 39 if(!dep[b]&&eg[i].l){ 40 dep[b]=dep[p]+1; 41 q.push(b); 42 } 43 } 44 } 45 return dep[T]!=0; 46 } 47 48 double dinic(int x,double y){ 49 if(x==T) return y; 50 double tmp=y; 51 if(cur[x]==-1) cur[x]=egh[x]; 52 for(int &i=cur[x];i;i=eg[i].ne){ 53 int b=eg[i].b; 54 if(dep[b]!=dep[x]+1||!eg[i].l) continue; 55 double re=dinic(b,min(eg[i].l,tmp)); 56 tmp-=re,eg[i].l-=re,eg[i^1].l+=re; 57 if(tmp<=1e-8) break; 58 }return y-tmp; 59 } 60 61 inline bool judge(double m){ 62 for(int i=2;i<=ect;i++) 63 eg[i].l=min(oril[i],m); 64 double l=0; 65 while(bfs()) l+=dinic(S,inf); 66 return fabs(maxl-l)<=1e-8; 67 } 68 69 int main(){ 70 //freopen("","r",stdin); 71 int i,j,k; 72 N=rd(),M=rd(),P=rd(); 73 S=1,T=N; 74 for(i=1;i<=M;i++){ 75 int a=rd(),b=rd(),c=rd(); 76 adeg(a,b,c); 77 } 78 while(bfs()) maxl+=dinic(S,inf); 79 double l=0,r=5e4,ans=5e4; 80 while(r-l>=1e-8){ 81 double m=(l+r)/2; 82 if(judge(m)) ans=m,r=m-1e-5; 83 else l=m+1e-5; 84 } 85 printf("%d\n",(int)maxl); 86 printf("%lf\n",ans*P); 87 return 0; 88 }