最大获利

Posted wjnclln

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大获利相关的知识,希望对你有一定的参考价值。

最大权闭合子图

#include<bits/stdc++.h>
#define N 120005  
#define M 400005  
#define INF 2100000000
using namespace std;
int n,m,T,ans,sum,S;
int to[M],nxt[M],w[M],li[N];
int cnt;
int d[N];
int q[N*2];
void Build(int x,int y,int z){
    to[++cnt]=y;
    nxt[cnt]=li[x];
    li[x]=cnt;
    w[cnt]=z;
    to[++cnt]=x;
    nxt[cnt]=li[y];
    li[y]=cnt;
    w[cnt]=0;
}
bool bfs(){
    memset(d,0,sizeof(d));
    int h,t,x;
    h=1;t=1;
    q[1]=S;
    d[S]=1;
    while (h!=t+1){
        x=q[h];
        for (int i=li[x];i>=0;i=nxt[i])
            if (w[i]&&!d[to[i]]){
                d[to[i]]=d[x]+1;
                q[++t]=to[i];
                if (t==N)
                    t=0;
            }
            if (++h==N)
                h=0;
    }
    if (d[T])
        return true;
    else
        return false;
}
int dfs(int x,int y){
    if (x==T||y==0)
        return y;
    int f,ret=0;
    for (int i=li[x];i>=0;i=nxt[i])
        if (d[to[i]]==d[x]+1){
            f=dfs(to[i],min(w[i],y));
            w[i]-=f;
            w[i^1]+=f;
            y-=f;
            ret+=f;
            if (y==0)
                break;
        }
    return ret;
}
int main(){
    scanf("%d%d",&n,&m);
    T=n+m+1;
    cnt=-1;
    for (int i=0;i<=T;i++)
        li[i]=-1;
    int x,y,z;
    for (int i=1;i<=n;i++){
        scanf("%d",&x);
        Build(0,i,x);
    }
     for(int i=1;i<=m;i++){  
        scanf("%d%d%d",&x,&y,&z);  
        Build(n+i,T,z);  
        Build(x,n+i,INF);  
        Build(y,n+i,INF);  
        sum+=z;  
    }
    while(bfs()) 
        ans+=dfs(S,INF);  
    printf("%d",sum-ans);  
}

 

以上是关于最大获利的主要内容,如果未能解决你的问题,请参考以下文章

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

最大获利

1497: [NOI2006]最大获利(最大权闭合子图)

最大获利

NOI2006 最大获利(最大权闭合子图)

bzoj1479[NOI2006]最大获利