http://codeforces.com/contest/802/problem/N
【题解】
方法一:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 #define N 200020 7 8 int to[N], head[N], nxt[N], cost[N], cap[N], cnt; 9 10 void init(){ memset(head, -1, sizeof head); } 11 12 void add_Edge(int S, int T, int c, int w){ 13 nxt[cnt] = head[S], cap[cnt] = c, cost[cnt] = w, to[cnt] = T, head[S] = cnt ++; 14 nxt[cnt] = head[T], cap[cnt] = 0, cost[cnt] = -w, to[cnt] = S, head[T] = cnt ++; 15 } 16 17 const LL INF = 1e14; 18 19 LL dist[N]; 20 int prv[N]; 21 bool vis[N]; 22 23 LL SPFA(int S, int T, int vet){ 24 queue <int> Q; 25 fill(prv, prv + vet, -1); 26 fill(dist, dist + vet, INF); 27 Q.push(S); dist[S] = 0, vis[S] = true; 28 while(!Q.empty()){ 29 int x = Q.front(); Q.pop(), vis[x] = false; 30 for(int id = head[x]; ~id; id = nxt[id]) if( cap[id] ){ 31 int y = to[id]; 32 if(dist[y] > dist[x] + cost[id]){ 33 dist[y] = dist[x] + cost[id]; 34 prv[y] = id; 35 if(!vis[y]) Q.push(y), vis[y] = true; 36 } 37 } 38 } 39 if(!~prv[T]) { return INF; } 40 41 for(int cur = T; cur != S; cur = to[cur^1]){ 42 cur = prv[cur]; 43 cap[cur] --; 44 cap[cur ^ 1] ++; 45 } 46 return dist[T]; 47 } 48 49 int a[N], b[N], n, k; 50 51 int main(){ 52 //freopen("in.txt", "r", stdin); 53 scanf("%d %d", &n, &k); 54 for(int i = 1; i <= n; i ++) scanf("%d", a + i); 55 for(int i = 1; i <= n; i ++) scanf("%d", b + i); 56 57 int S = 0, T = 2 * n + 1; 58 init(); 59 for(int i = 1; i <= n; i ++){ 60 add_Edge(S, i, 1, a[i]); 61 add_Edge(i + n, T, 1, b[i]); 62 add_Edge(i, i + n, n, 0); 63 if(i < n) add_Edge(i + n, i + n + 1, n - i, 0); 64 } 65 LL ans = 0; 66 for(int i = 1; i <= k; i ++) ans += SPFA(S, T, T + 1); 67 cout << ans << endl; 68 }