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\n",res-dinic(n+m+1));
return 0;
}