羅区P4174 [NOI2006]最大の利益

タイトル:羅区P4174 [NOI2006]最大の利益

アイデア:

最大重量閉鎖サブグラフモデル
この問題の次のように、それは理解することができます:
まず、我々は、すべてのユーザーがメリットを得ることができ、これらの利点は、初期の答えとして、アップ追加することを前提としています。
しかし、これらの利益は、すべてのことが、私たちはどちらかのいくつかのトランジットステーションを構築する、または一部のユーザーを与えるトランジット駅の建設せずに行うことはできません。これらは、総収入が減少しますので、私たちは、削減の最小量を取得しようとしなければなりません。
次のように図内蔵:転写ステーション及びサービスのユーザとの間のエッジINFの容量を接続することができます。すべての側面に接続された中継局からスーパーソースシンクS、T、Sを追加し、エッジTに接続された搬送ステーションの建設費の容量は、すべてのユーザーのための容量は、ユーザから恩恵を受ける。
図は、示された意味として、最小カットを計算する:INFは明らかに端部を切断しません。中継局Sにエッジのカットオフは、移送ステーションの構成を示していない場合したがって、;もしTのユーザ側、ユーザゲイン免除を遮断します。
それは、少なくとも私たちは利益を放棄せるのに同等の最小カット、最小の最終結果であるため。
そして、答えを得るために最初の総収入とメリット(最小カットを)放棄する少なくとも引きます。


コード:

#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;
}

おすすめ

転載: www.cnblogs.com/yu-xing/p/11323095.html