标签:cos ++ 无法 rev http out get first dijkstra
http://acm.hdu.edu.cn/showproblem.php?pid=6611
题很简单,一眼拆点费用流
就是点边拉满之后复杂度有点恐怖,比赛的时候没敢莽费用流
但是最后居然真的是费用流,不过必须上原始对偶且用Dijkstra增广
具体细节很多,大概就是指,原本的Dijktra无法处理负权图,我们就去想办法对所有的费用进行统一扩大,变成正权最短路.
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #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) #pragma GCC optimize(2) const int maxn=4e3+30; const int INF=1e9; using namespace std; struct mcf{public: #define tpp int struct node{short to;tpp cap;tpp cost;int rev;}; short prev[maxn],pree[maxn]; tpp dis[maxn],cost,h[maxn]; int f; vector<node> g[maxn]; void init(int n=maxn-2){rep(i,0,n+1) g[i].clear();} inline void add(int from,int to,tpp cap,tpp cost){ g[from].push_back({to,cap,cost,(int)g[to].size()}); g[to].push_back({from,0,-cost,(int)g[from].size()-1}); } tpp getcost(int s,int t,int flow=INF){ f=0,cost=0; fill(h,h+1+t,0); while(flow){ #define pdi pair<tpp,short> priority_queue<pdi,vector<pdi>,greater<pdi> >que; fill(dis,dis+t+1,INF); dis[s]=0;que.push(mp(0,s)); while(!que.empty()){ auto now=que.top();que.pop(); if(dis[now.se]<now.fi)continue; int x=now.se,cnt=0; for(auto &i:g[x]) if(i.cap>0&&dis[i.to]>dis[x]+h[x]-h[i.to]+i.cost){ dis[i.to]=dis[x]+i.cost+h[x]-h[i.to]; prev[i.to]=x,pree[i.to]=cnt++; que.push(mp(dis[i.to],i.to)); }else cnt++; } if(dis[t]==INF)break; rep(i,0,t+1) h[i]+=dis[i]; tpp d=flow; for(int now=t;now!=s;now=prev[now])d=min(d,g[prev[now]][pree[now]].cap); flow-=d,f+=d;cost+=d*h[t]; for(int now=t;now!=s;now=prev[now]){ node &e=g[prev[now]][pree[now]]; e.cap-=d,g[now][e.rev].cap+=d; } } return cost; } }net; int casn,n,k,m; int a[maxn/2]; int main() {IO; cin>>casn; while(casn--){ cin>>n>>k; net.init(n*2+10); int ss=n*2+1,t=n*2+3,s=n*2+2; rep(i,1,n) cin>>a[i]; rep(i,1,n){ net.add(i,i+n,1,-a[i]); net.add(ss,i,1,0); net.add(i+n,t,1,0); rep(j,i+1,n) if(a[i]<=a[j]) net.add(i+n,j,1,0); } net.add(s,ss,k,0); cout<<-net.getcost(s,t)<<endl; } }
hdu6611 2019 多校3K 原始对偶费用流(正权化Dijkstra找增广路)
标签:cos ++ 无法 rev http out get first dijkstra
原文地址:https://www.cnblogs.com/nervendnig/p/11267010.html