codeforces 1082G - Petya and Graph 最大权闭合子图 网络流

题意:

让你选一些边,选边的前提是端点都被选了,求所有的边集中,边权和-点权和最大的一个。

题解:

对于每个边建一个点,然后就是裸的最大权闭合子图,

结果比赛的时候我的板子太丑,一直T,(不会当前弧优化...)

当时补题用的是蔡队的Dinic当前弧优化板子

今天重写了一遍

#include <bits/stdc++.h>
#define endl '\n'
#define ll long long
#define all(x) x.begin(),x.end()
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
using namespace std;
const int mod=1e9+7;
const double PI=acos(-1.0);
const int maxn=1e6+7,maxm=2e6+7;
//head
ll n,m,s,t;
class graph{
public:
	struct edge{
		int from,to;ll cap,flow;
		edge(int a,int b,ll c,ll d){from=a,to=b,cap=c,flow=d;}
	};
	vector<vector<edge>> node;
	graph(int n=maxn){node.resize(n+2);}
	void add(int a,int b,ll c,ll d){
		node[a].emplace_back(a,b,c,d);
	}
};

const ll INF = 1e18;
class dinic:public graph{
public:
	int n,m,s,t;
	vector<edge> edges;
	vector<vector<int>> v;
	vector<bool> vis;
	vector<int> dis,cur;
	dinic(int nn=maxn){
		node.resize(nn+2);
		v.resize(nn+2);
		n=nn;
		m=0;
	}
	void add(int a, int b, ll c){
		edges.emplace_back(a,b,c,0);
		edges.emplace_back(b,a,0,0);
		v[a].emplace_back(m++);
		v[b].emplace_back(m++);
		//node[a].emplace_back(a,b,c,0);
		//node[b].emplace_(b,a,0,0);
	}
	bool bfs(){
		fill(all(vis),false);
		fill(all(dis),0);
		queue<int> q;
		q.push(s);
		dis[s]=0;
		vis[s]=1;
		while(!q.empty()) {
			int now=q.front();q.pop();
			for(auto &i:v[now]) {
				edge &e=edges[i];
				if(!vis[e.to]&&e.cap>e.flow){
					vis[e.to]=1;
					dis[e.to]=dis[now]+1;
					q.push(e.to);
				}
			}
		}
		return vis[t];
	}
	ll dfs(int now, ll a){
		if (now==t||a==0) return a;
		ll flow=0,f;
		int mm=v[now].size();
		for(int &i=cur[now];i<mm;i++){
			edge &e=edges[v[now][i]];
			if(dis[now]+1==dis[e.to]&&(f= dfs(e.to,min(a,e.cap-e.flow)))>0){
				e.flow+=f;
				edges[v[now][i]^1].flow-=f;
				flow+=f;
				a-=f;
				if(a==0) break;
			}
		}
		return flow;
	}
	ll mf(int ss,int tt){
		s=ss,t=tt;
		dis.resize(n+2);
		cur.resize(n+2);
		vis.resize(n+2);
		ll flow=0;
		while(bfs()){
			fill(all(cur),0);
			flow+=dfs(s,INF);
		}
		return flow;
	}
};

int main() {
	IO;
	cin>>n>>m;
	int tt=n+m+1,ss=0;
	dinic g(n+m+2);
	rep(i,1,n) {
		ll a;cin>>a;
		if(a>0) g.add(i,tt,a);
	}
	ll sum=0;
	rep(i,1,m) {
		int a,b,c;cin>>a>>b>>c;
		sum+=c;
		g.add(i+n,a,INF);
		g.add(i+n,b,INF);
		g.add(ss,i+n,c);
	}
	cout<<sum-g.mf(ss,tt)<<endl;
	return 0;
}
posted @ 2019-01-07 13:08  nervending  阅读(268)  评论(0编辑  收藏  举报