• BZOJ 1497 JZYZOJ 1344 [NOI2006]最大获利 网络流 最大权闭合图


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

     
    思路:(最大权闭合图的思路相同)
    将所有的用户群获利(正值)作为一个点连一条权值为获利值的边到st点,将所有的建站消耗(输入的是正值但是是在获利中减去的所以实质还是负值)作为一个点连一条权值为消耗值的边到ed点,再将每个用户群点和其依赖的建站点连一条权值为无穷的边,求st到ed的最大流。
    此时,所求的最大获利=所有用户群获利的和-最大流。
    某条st到ed的路如果得不偿失,贡献的值就是用户群获利的值;否则,贡献值为建站消耗,从而起到了选择的作用。
     
    算是网络流的复习,用奇怪的优化过的dinic才不会超时,其他的方法算最大流都是80分。
    dinic的写法和我以前看到的不一样,减少了return次数从而减少了dfs的次数,让每次dfs的值就是目前图中所有路(不重合)能得到的值,大大节省了时间。
     
    代码
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #include<vector>
     8 using namespace std;
     9 const int maxn=55010;
    10 const int minf=1<<30;
    11 int n,m;
    12 int a[maxn]={};
    13 int vis[maxn]={};
    14 struct nod{
    15     int y,next,v,rev;
    16 }e[maxn*10];
    17 int head[maxn],dep[maxn],tot=0;
    18 void init(int x,int y,int v){
    19     e[++tot].y=y;e[tot].v=v;e[tot].next=head[x],e[tot].rev=tot+1;
    20     head[x]=tot;
    21     e[++tot].y=x;e[tot].v=0;e[tot].next=head[y],e[tot].rev=tot-1;
    22     head[y]=tot;
    23 }
    24 int bfs(int st,int ed){
    25     queue<int>q;
    26     memset(dep,-1,sizeof(dep));
    27     dep[st]=0;q.push(st);
    28     int x,y,v;
    29     while(!q.empty()){
    30         x=q.front();q.pop();
    31         for(int i=head[x];i;i=e[i].next){
    32             y=e[i].y;v=e[i].v;
    33             if(dep[y]==-1&&v){
    34                 dep[y]=dep[x]+1;q.push(y);
    35             }
    36         }
    37     }
    38     return dep[ed]!=-1;
    39 }
    40 int dfs(int x,int ed,int mi){
    41     if(x==ed)return mi;
    42     int y,v,f,tsn=0;
    43     for(int i=head[x];i;i=e[i].next){
    44         y=e[i].y;v=e[i].v;
    45         if(v&&dep[y]==dep[x]+1){
    46             f=dfs(y,ed,min(mi-tsn,v));
    47             e[i].v-=f;
    48             e[e[i].rev].v+=f;
    49             tsn+=f;
    50             if(tsn==mi)return tsn;
    51         }
    52     }
    53     if(!tsn)dep[x]=-1;
    54     return tsn;
    55     
    56 }
    57 int dinic(int st,int ed){
    58     int ans=0;
    59     while(bfs(st,ed)){
    60         ans+=dfs(st,ed,minf);
    61     }
    62     return ans;
    63 }
    64 int main(){
    65     scanf("%d%d",&n,&m);
    66     int x,y,v,st=n+m+1,ed;
    67     ed=st+1;
    68     int ans=0;
    69     for(int i=1;i<=n;i++){
    70         scanf("%d",&a[i]);
    71         init(i,ed,a[i]);
    72     }
    73     for(int i=1;i<=m;i++){
    74         scanf("%d%d%d",&x,&y,&v);
    75         ans+=v;
    76         init(i+n,x,minf);
    77         init(i+n,y,minf);
    78         init(st,i+n,v);
    79     }
    80     printf("%d
    ",ans-dinic(st,ed));
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    针对Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1的解决方案
    MAC配置C++运行环境
    Keras 模型相关操作
    微信小程序 WXS
    vue 长列表优化
    webpack4 SplitChunks插件 代码拆分
    node path api
    mysql的模型依赖说明
    MySQL和MyCat replace
    SQL Server中WITH(NOLOCK)提示用在视图上会怎样(转载)
  • 原文地址:https://www.cnblogs.com/137shoebills/p/7786985.html
Copyright © 2020-2023  润新知