Luo Gu P4174 [NOI2006] maximum profit

Title: Luo Gu P4174 [NOI2006] maximum profit

Ideas:

Maximum weight closure sub-graph model
of this problem, it can be understood as follows:
First, we assume that all users can get benefits, these benefits add up, as the initial answer.
But these gains will not be possible without the construction of a transit station will all be, we either build some transit stations, or give up some users. These will reduce total revenue, so we have to try to get the minimum amount of reduction.
FIG built as follows: between the transfer station and the service user can connect capacity of edge inf. Add super source sink s, t, s from the relay station connected to all sides, the capacity of the construction cost of the transfer station, connected to the edges t, capacity for all users benefit from the user.
FIG calculate the minimum cut, as indicated meaning: inf obviously not cut off edges. Therefore, if the cut off of the edge to the relay station s, not showing the construction of the transfer station; cut off if the user side of t, the user gains a waiver.
Because it is at least the minimum cut, the final result of the minimum, equivalent to let us give up the gains.
Then subtract at least to give up benefits (minimum cut) with an initial total revenue to get the answer.


Code:

#include <bits/stdc++.h>
using namespace std;
const int N=2e6+5,inf=0x3f3f3f3f;
int n,m,s,t,tot,ans,d[N];
int Top=1,ver[N],nxt[N],val[N],head[N];
inline void add(int u,int v,int w){
    ver[++Top]=v;val[Top]=w;nxt[Top]=head[u];head[u]=Top;
    ver[++Top]=u;val[Top]=0;nxt[Top]=head[v];head[v]=Top;
}
bool bfs(){
    for(int i=1;i<=tot;++i) d[i]=0;
    queue<int> q;
    q.push(s);
    d[s]=1;
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=head[u];i;i=nxt[i]){
            int v=ver[i];
            if(val[i]&&!d[v]){
                d[v]=d[u]+1;
                if(v==t) return true;
                q.push(v);
            }
        }
    }
    return false;
}
int dfs(int u,int flow){
    if(u==t) return flow;
    int left=flow;
    for(int i=head[u];i&&left;i=nxt[i]){
        int v=ver[i];
        if(val[i]&&d[v]==d[u]+1){
            int res=dfs(v,min(left,val[i]));
            if(!res) d[v]=0;
            val[i]-=res;
            val[i^1]+=res;
            left-=res;
        }
    }
    return flow-left;
}
int main(){
    scanf("%d%d",&n,&m);
    tot=n+m;
    s=++tot;
    t=++tot;
    for(int i=1,w;i<=n;++i){
        scanf("%d",&w);
        add(s,i,w);
    }
    for(int i=1,a,b,c;i<=m;++i){
        scanf("%d%d%d",&a,&b,&c);
        add(a,n+i,inf);
        add(b,n+i,inf);
        add(n+i,t,c);
        ans+=c;
    }
    while(bfs()) ans-=dfs(s,inf);
    printf("%d",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/yu-xing/p/11323095.html