• BZOJ 1497 最大获利(最大权闭合子图)


    http://www.lydsy.com/JudgeOnline/problem.php?id=1497

    思路:由题意可以得知,每个顾客都依赖2个中转站,那么让中转站连有向边到汇点,流量为它的建设费用,源点连到每个顾客,流量为赚的钱,然后每个顾客到它依赖的中转站连流量为inf的边

     1 #include<algorithm>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<iostream>
     6 #define inf 0x7fffffff
     7 int tot,go[500005],first[500005],next[500005],flow[500005];
     8 int op[500005],S,T,nodes,dis[500005],cnt[500005],n,m;
     9 int read(){
    10     int t=0,f=1;char ch=getchar();
    11     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    12     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
    13     return t*f;
    14 }
    15 void insert(int x,int y,int z){
    16     tot++;
    17     go[tot]=y;
    18     next[tot]=first[x];
    19     first[x]=tot;
    20     flow[tot]=z;
    21 }
    22 void add(int x,int y,int z){
    23     insert(x,y,z);op[tot]=tot+1;
    24     insert(y,x,0);op[tot]=tot-1;
    25 }
    26 int dfs(int x,int f){
    27     if (x==T) return f;
    28     int mn=nodes,sum=0;
    29     for (int i=first[x];i;i=next[i]){
    30         int pur=go[i];
    31         if (flow[i]&&dis[pur]+1==dis[x]){
    32             int save=dfs(pur,std::min(f-sum,flow[i]));
    33             sum+=save;
    34             flow[i]-=save;
    35             flow[op[i]]+=save;
    36             if (f==sum||dis[S]>=nodes) return sum;
    37         }
    38         if (flow[i]) mn=std::min(mn,dis[pur]); 
    39     }
    40     if (sum==0){
    41         cnt[dis[x]]--;
    42         if (cnt[dis[x]]==0){
    43             dis[S]=nodes;
    44         }
    45         else{
    46             dis[x]=mn+1;
    47             cnt[dis[x]]++;
    48         }
    49     }
    50     return sum;
    51 }
    52 int main(){
    53     n=read(),m=read();
    54     nodes=n+m+2;
    55     T=n+m+1;S=0;
    56     for (int i=1;i<=n;i++){
    57      int x=read();
    58      add(m+i,T,x);
    59     }
    60     int sum=0;
    61     for (int i=1;i<=m;i++){
    62         int x=read(),y=read(),z=read();
    63         add(S,i,z);
    64         add(i,x+m,inf);
    65         add(i,y+m,inf);
    66         sum+=z;
    67     }
    68     int ans=0;
    69     while (dis[S]<nodes) ans+=dfs(S,inf);
    70     printf("%d
    ",std::max(sum-ans,0));
    71 }
  • 相关阅读:
    html标题-段落-字符实体-换行
    html概述和html基本结构:
    可以在一个.java文件中写两个类吗?
    栈内存和堆内存的区别
    Java的访问权限
    (转)第三方支付的盈利模式
    (转)第三方支付参与者
    直联和间联的区别——直连和间连的区别
    HashSet和LinkedHashSet特点.
    Map和TreeMap的特点
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5578568.html
Copyright © 2020-2023  润新知