【HDOJ6611】K Subsequence(费用流)

时间:2019-09-29
本文章向大家介绍【HDOJ6611】K Subsequence(费用流),主要包括【HDOJ6611】K Subsequence(费用流)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题意:给定一个长为n的正整数序列,要求从中取出至多k个不下降序列,使得它们的和最大,求这个和

n<=2e3,k<=10,a[i]<=1e5

思路:极其考验模板,反正我的spfa和zkw都挂了,就拿这题std做dijkstra费用流的板子了

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 typedef vector<PII> VII;
 10 typedef pair<ll,ll>P;
 11 #define N  10000
 12 #define M  2100000
 13 #define fi first
 14 #define se second
 15 #define MP make_pair
 16 #define pb push_back
 17 #define pi acos(-1)
 18 #define mem(a,b) memset(a,b,sizeof(a))
 19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 21 #define lowbit(x) x&(-x)
 22 #define Rand (rand()*(1<<16)+rand())
 23 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 24 #define ls p<<1
 25 #define rs p<<1|1
 26 
 27 const int MOD=998244353,inv2=(MOD+1)/2;
 28       double eps=1e-4;
 29       int INF=0x7fffffff;;
 30       ll inf=5e13;
 31       int dx[4]={-1,1,0,0};
 32       int dy[4]={0,0,-1,1};
 33 
 34 struct edge
 35 {
 36     int to,cap,cost,rev;
 37     edge(){}
 38     edge(int a,int b,int c,int d):
 39     to(a),cap(b),cost(c),rev(d){}
 40 };
 41 
 42 int read()
 43 {
 44    int v=0,f=1;
 45    char c=getchar();
 46    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 47    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 48    return v*f;
 49 }
 50 
 51 struct MCMF
 52 {
 53     int V,h[N],dis[N],preV[N],preE[N];
 54     vector<edge> g[N];
 55 
 56     void init(int n)
 57     {
 58         V=n;
 59         rep(i,0,V) g[i].clear();
 60     }
 61 
 62     void add(int u,int v,int cap,int cost)
 63     {
 64         g[u].pb(edge(v,cap,cost,g[v].size()));
 65         g[v].pb(edge(u,0,-cost,g[u].size()-1));
 66     }
 67 
 68     int minc_mf(int S,int T,int f,int &flow)
 69     {
 70         int res=0;
 71         fill(h,h+1+V,0);
 72         while(f)
 73         {
 74             priority_queue <PII,vector<PII>, greater<PII> > q;
 75             fill(dis,dis+1+V,INF);
 76             dis[S]=0;
 77             q.push(MP(0,S));
 78             while(!q.empty())
 79             {
 80                 PII now=q.top(); q.pop();
 81                 int u=now.se;
 82                 if(dis[u]<now.fi) continue;
 83                 for(int i=0;i<g[u].size();i++)
 84                 {
 85                     edge e=g[u][i];
 86                     int v=e.to;
 87                     if(e.cap>0&&dis[v]>dis[u]+e.cost+h[u]-h[v])
 88                     {
 89                         dis[v]=dis[u]+e.cost+h[u]-h[v];
 90                         preV[v]=u;
 91                         preE[v]=i;
 92                         q.push(MP(dis[v],v));
 93                     }
 94 
 95                 }
 96             }
 97             if(dis[T]==INF) break;
 98             rep(i,0,V) h[i]+=dis[i];
 99             int t=f,k=T;
100             while(k!=S)
101             {
102                 int e=preE[k];
103                 t=min(t,g[preV[k]][preE[k]].cap);
104                 k=preV[k];
105             }
106             f-=t; flow+=t; res+=t*h[T];
107             k=T;
108             while(k!=S)
109             {
110                 edge &e=g[preV[k]][preE[k]];
111                 e.cap-=t;
112                 g[k][e.rev].cap+=t;
113                 k=preV[k];
114             }
115         }
116         return res;
117     }
118 }mcmf;
119 
120 int num[N][2],a[N],S,T,s,flow;
121 
122 int main()
123 {
124     int cas=read();
125     s=0;
126     while(cas--)
127     {
128         int n=read(),k=read();
129         rep(i,1,n) a[i]=read();
130         s=0;
131         rep(i,1,n)
132         {
133             num[i][0]=++s;
134             num[i][1]=++s;
135         }
136         S=++s; s++; T=++s;
137         mcmf.init(s);
138         mcmf.add(S,S+1,k,0);
139         rep(i,1,n) mcmf.add(S+1,num[i][0],1,0);
140         rep(i,1,n) mcmf.add(num[i][0],num[i][1],1,-a[i]);
141         rep(i,1,n)
142          rep(j,i+1,n)
143           if(a[j]>=a[i]) mcmf.add(num[i][1],num[j][0],1,0);
144         rep(i,1,n) mcmf.add(num[i][1],T,1,0);
145         flow=0;
146         int ans=-mcmf.minc_mf(S,T,INF,flow);
147         printf("%d\n",ans);
148     }
149     return 0;
150 }

原文地址:https://www.cnblogs.com/myx12345/p/11608725.html