2024 Jiangsu Collegiate Programming Contest H
记录一下为数不多的网络流
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
#include <execution>
using namespace std;
using i64 = long long;
using i128 = __int128;
template <typename T>struct MCFgraph{
struct edge{
int v;T c,f;
edge(int v,T c,T f):v(v),c(c),f(f){}
};
const int n;
vector<edge> e;
vector<vector<int>> g;
vector<i64> h,dis;
vector<int> pre;
bool dij(int s,int t){
dis.assign(n,numeric_limits<i64>::max());pre.assign(n,-1);
priority_queue<pair<i64,int>,vector<pair<i64,int>>,greater<pair<i64,int>>> q;
dis[s]=0;q.emplace(0,s);
while(!q.empty()){
i64 d = q.top().first;int u = q.top().second;q.pop();
for(int i:g[u]){
int v = e[i].v;
T c = e[i].c;
T f = e[i].f;
if(c>0&&dis[v]>d+h[u]-h[v]+f){
dis[v] = d+h[u]-h[v]+f;
pre[v]=i;
q.emplace(dis[v],v);
}
}
}
return dis[t]!=numeric_limits<i64>::max();
}
MCFgraph(int n):n(n),g(n){}
void addedge(int u,int v,T c,T f){
g[u].push_back(e.size());
e.emplace_back(v,c,f);
g[v].push_back(e.size());
e.emplace_back(u,0,-f);
}
pair<T,i64> flow(int s,int t){
T flow = 0;i64 cost = 0;h.assign(n,0);
while(dij(s,t)){
for(int i = 0;i<n;++i) h[i]+=dis[i];
T aug = numeric_limits<i64> ::max();
for(int i = t;i!=s;i = e[pre[i]^1].v) aug= min(aug,e[pre[i]].c);
for(int i = t;i!=s;i = e[pre[i]^1].v){e[pre[i]].c-=aug;e[pre[i]^1].c+=aug;}
flow+=aug;cost+=i64(aug*h[t]);
}
return make_pair(flow,cost);
}
};
using mcf = MCFgraph<i64>;
void solve(){
int n;
cin>>n;
mcf g(4*n+10);//0,4*n+1 (i-1)*3+1+2+3
int id=3*n+1;
constexpr i64 inf = 1e18;
vector<int> a(n+1);
for(int i = 1;i<=n;++i){
int op;
cin>>op;
if(i+1<=n){
g.addedge((i-1)*3+1,i*3+1,inf,0);
g.addedge((i-1)*3+2,i*3+2,inf,0);
g.addedge((i-1)*3+3,i*3+3,inf,0);
}
if(op==1){
cin>>a[i];
g.addedge(0,id,1,0);
g.addedge(id,(i-1)*3+1,1,1);
g.addedge(id,(i-1)*3+2,1,(a[i]+9)/10);
g.addedge(id,(i-1)*3+3,1,0);
g.addedge(id,4*n+1,1,a[i]);
id++;//更新id
}else{
g.addedge((i-1)*3+1,4*n+1,1,0);
g.addedge((i-1)*3+2,4*n+1,1,0);
g.addedge((i-1)*3+3,4*n+1,1,0);
}
}
i64 sum = reduce(std::execution::par,a.begin()+1,a.end(),0);
cout<<sum-g.flow(0,4*n+1).second<<"\n";
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
int t=1;
cin>>t;
while(t--) solve();
return 0;
}