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