Codeforces 1082 G(最大权闭合子图)

传送门

题意:

有一张图,点权为$a_i$,边权为 $w_i$ ,求这张图的最大权闭合子图

分析:

这……最大权闭合子图裸题?甚至题意都没有任何隐藏

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=10005;
const ll inf=0x3f3f3f3f3f3f3f3f;
struct Node{
    int to,next;
    ll val;
}q[maxn<<1];
int head[maxn],cnt=0,cur[maxn],vis[maxn];
ll dep[maxn],maxflow;
int sp,ep;
void init(){
    memset(head,-1,sizeof(head));
    cnt=2,maxflow=0;
}
void add_edge(int from,int to,ll val){
    q[cnt].to=to;
    q[cnt].val=val;
    q[cnt].next=head[from];
    head[from]=cnt++;

    q[cnt].to=from;
    q[cnt].val=0;
    q[cnt].next=head[to];
    head[to]=cnt++;
}
bool bfs(int n){
    for(int i=0;i<=n;i++){
        cur[i]=head[i],dep[i]=inf;
        vis[i]=0;
    }
    dep[sp]=0;
    queue<int>que;
    que.push(sp);
    while(!que.empty()){
        int x=que.front();
        que.pop();
        vis[x]=0;
        for(int i=head[x];i!=-1;i=q[i].next){
            int to=q[i].to;
            if(dep[to]>dep[x]+1&&q[i].val){
                dep[to]=dep[x]+1;
                if(!vis[to]){
                    que.push(to);
                    vis[to]=1;
                }
            }
        }
    }
    if(dep[ep]!=inf) return true;
    else return false;
}
ll dfs(int x,ll flow){
    ll rlow=0;
    if(x==ep){
        maxflow+=flow;
        return flow;
    }
    ll used=0;
    for(int i=cur[x];i!=-1;i=q[i].next){
        cur[x]=i;
        int to=q[i].to;
        if(q[i].val&&dep[to]==dep[x]+1){
            if(rlow=dfs(to,min(flow-used,q[i].val))){
                used+=rlow;
                q[i].val-=rlow;
                q[i^1].val+=rlow;
                if(used==flow) break;
            }
        }
    }
    return used;
}
ll dinic(int n){
    while(bfs(n)){
        dfs(sp,inf);
    }
    return maxflow;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    init();
    sp=0,ep=n+m+1;
    for(int i=1;i<=n;i++){
        int vals;
        scanf("%d",&vals);
        add_edge(i+m,ep,vals);
    }
    ll res=0;
    for(int i=1;i<=m;i++){
        int from,to;
        ll val;
        scanf("%d%d%lld",&from,&to,&val);
        add_edge(sp,i,val);
        add_edge(i,m+from,inf);
        add_edge(i,m+to,inf);
        res+=val;
    }
    printf("%lld
",res-dinic(n+m+1));
    return 0;
}

原文地址:https://www.cnblogs.com/Chen-Jr/p/11007133.html