[NOI2006] 最大获利

题面

 

    最大权闭合子图模板题,这里就不提了,留个网络流的板板

 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
#define pb push_back
const int N=60005;

vector<int> g[N];
struct lines{
	int to,flow,cap;
}l[400005];
int num=-1,cur[N],d[N],n,m,S,T,tt;
bool v[N];

inline void add(int x,int y,int z){
	l[++num]=(lines){y,0,z},g[x].pb(num);
	l[++num]=(lines){x,0,0},g[y].pb(num);
}

inline bool bfs(){
	queue<int> q;
	memset(v,0,sizeof(v));
	q.push(S),v[S]=1,d[S]=0;
	
	for(int x;!q.empty();){
		x=q.front(),q.pop();
		
		for(int e:g[x]) if(l[e].flow<l[e].cap&&!v[l[e].to]){
			v[l[e].to]=1,d[l[e].to]=d[x]+1;
			q.push(l[e].to);
		}
	}
	
	return v[T];
}

int dfs(int x,int A){
	if(x==T||!A) return A;
	
	int f,flow=0,sz=g[x].size();
	for(int &i=cur[x];i<sz;i++){
		lines &e=l[g[x][i]];
		if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(A,e.cap-e.flow)))){
			A-=f,flow+=f;
			e.flow+=f,l[g[x][i]^1].flow-=f;
			if(!A) break;
		}
	}
	
	return flow;
}

inline int max_flow(){
	int an=0;
	while(bfs()){
		memset(cur,0,sizeof(cur));
		an+=dfs(S,1<<30);
	}
	return an;
}

inline void build(){
	scanf("%d%d",&n,&m),T=n+m+1;
	for(int i=1,val;i<=n;i++)
	    scanf("%d",&val),add(S,i,val);
	   
	for(int i=1,val,U,V;i<=m;i++){
		scanf("%d%d%d",&U,&V,&val),tt+=val; 
		add(i+n,T,val),add(U,i+n,1<<30),add(V,i+n,1<<30);
	}
}

int main(){
	build();
	printf("%d\n",tt-max_flow());
	return 0;
}

  

posted @ 2019-08-02 10:30  蒟蒻JHY  阅读(189)  评论(0编辑  收藏  举报