• 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
    ",(int)maxl);
    86     printf("%lf
    ",ans*P);
    87     return 0;
    88 }
  • 相关阅读:
    整理Xen理论知识
    搭建Hadoop
    Java、中Date的格式初始化以及Calendar的使用
    学习Xen
    关于mpi的理论知识以及编写程序来实现数据积分中的梯形积分法。
    题解-CF1396C Monster Invaders
    题解-CF1139D Steps to One
    qq 表情库
    题解-洛谷P6788 「EZEC-3」四月樱花
    题解-CF1401E Divide Square
  • 原文地址:https://www.cnblogs.com/Ressed/p/9816437.html
Copyright © 2020-2023  润新知