日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Gym 101190D BZOJ 4842 Luogu P6967 LOJ #6071 [NEERC2016]Delight for a Cat (费用流)

發(fā)布時間:2025/3/15 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Gym 101190D BZOJ 4842 Luogu P6967 LOJ #6071 [NEERC2016]Delight for a Cat (费用流) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目鏈接

(BZOJ) 大人,時代變了
(Gym) https://codeforces.com/gym/101190
(Luogu) https://www.luogu.com.cn/problem/P6967
(LOJ) https://loj.ac/p/6079

題解

想了一晚上,終于有點理解了,好神仙啊。
我只會純網(wǎng)絡流的做法,并不會線性規(guī)劃。

首先題意顯然是有一個序列每個位置可以選 \(0\)\(1\),收益分別是 \(a_i\)\(b_i\),且滿足每個長度為 \(m\) 的區(qū)間里選 \(1\) 的個數(shù)在 \([L,R]\) 內(nèi)。
區(qū)間個數(shù)的限制似乎在網(wǎng)絡流中難以體現(xiàn),于是有一種思路是把區(qū)間和點進行轉(zhuǎn)化。也就是我們有 \((n-m+1)\) 種區(qū)間,不妨設按照左端點編號,那么對于每個點,如果選了 \(1\) 會給編號在一個區(qū)間內(nèi)的區(qū)間的選 \(1\) 個數(shù)增加 \(1\)(或者選 \(0\) 的個數(shù)減少 \(1\))。這個在網(wǎng)絡流中的體現(xiàn)是用一條邊從 \(i\) 指向 \((i+m)\),分走 \(1\) 的流量,后面再還回來。
那么就有了一個上下界費用流的建圖:建立源點 \(S\)\(0,1,2,...,n-m+1\),連邊 \((S,0,[0,m],0),(i,i+1,[n-R,n-L],0),(\max(0,i-m),\min(n-m+1,i),[0,1],b_i-a_i)\),然后求 \(S\)\((n-m+1)\) 的最大費用最大流,答案再加上 \(\sum^n_{i=1}a_i\). 一單位的流量流過 \((i,i+1)\) 代表選了 \(0\),否則代表選了 \(1\).
但這樣似乎并不優(yōu)美。考慮優(yōu)化成不帶上下界的費用流。
我們其實沒有必要拘泥于讓 \((i,i+1)\) 流過一單位流量代表選了 \(0\). 我們只要把 \(1\) 的選出來就好了!我們從源點往 \(0\) 連流量為 \(R\) 的邊,代表任何時刻不可能分走超過 \(R\) 的流量。然后再將 \((i,i+1)\) 的邊流量設置為 \(R-L\),意味著至少有 \(L\) 的流量要被分走。
于是做完了,時間復雜度 \(O(MFMC(n,2n))\).

代碼

太久沒寫網(wǎng)絡流了,甚至拉完板子后忘記了邊數(shù)要初始化成 \(1\)……

#include<bits/stdc++.h> #define llong long long #define mkpr make_pair #define x first #define y second #define iter iterator #define riter reverse_iterator #define y1 Lorem_ipsum_ #define tm dolor_sit_amet_ using namespace std;inline int read() {int x = 0,f = 1; char ch = getchar();for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}return x*f; }namespace NetFlow {const int N = 1002;const int M = 2002;const llong INF = 1e13;struct Edge{int u,v,nxt,w; llong c;} e[(M<<1)+3];int fe[N+3];llong dis[N+3];int que[N+5];bool inq[N+3];int lst[N+3];int n,m,en,s,t; llong mf,mc;void addedge(int u,int v,int w,llong c){en++; e[en].u = u,e[en].v = v,e[en].w = w,e[en].c = c;e[en].nxt = fe[u]; fe[u] = en;en++; e[en].u = v,e[en].v = u,e[en].w = 0,e[en].c = -c;e[en].nxt = fe[v]; fe[v] = en;}bool spfa(){for(int i=1; i<=n; i++) dis[i] = -INF;int hd = 1,tl = 2; que[1] = s; dis[s] = 0; inq[s] = true;while(hd!=tl){int u = que[hd]; hd++; if(hd>n+1) hd-=n+1;for(int i=fe[u]; i; i=e[i].nxt){int v = e[i].v;if(e[i].w>0&&dis[e[i].v]<dis[u]+e[i].c){dis[e[i].v] = dis[u]+e[i].c; lst[e[i].v] = i;if(!inq[e[i].v]){inq[e[i].v] = true;que[tl] = e[i].v; tl++; if(tl>n+1) tl-=n+1;}}}inq[u] = false;}return dis[t]!=-INF;}void calcflow(){int flow = 1e5;for(int u=t; u!=s; u=e[lst[u]].u){flow = min(flow,e[lst[u]].w);}for(int u=t; u!=s; u=e[lst[u]].u){e[lst[u]].w -= flow; e[lst[u]^1].w += flow;}mf += flow; mc += 1ll*flow*dis[t];}llong mfmc(int _n,int _s,int _t){n = _n,s = _s,t = _t; mf = 0,mc = 0ll;while(spfa()) {calcflow();} return mc;} } using NetFlow::addedge; using NetFlow::mfmc;const int mxN = 1000; int n,m,al,ar; llong a[mxN+3],b[mxN+3];int main() {n = read(),m = read(),ar = m-read(),al = read(); NetFlow::en = 1;for(int i=1; i<=n; i++) a[i] = read(); for(int i=1; i<=n; i++) b[i] = read();llong ans = 0ll;for(int i=1; i<=n; i++) ans += a[i];addedge(1,2,ar,0);for(int i=1; i<=n; i++){addedge(max(0,i-m)+2,min(n-m+1,i)+2,1,b[i]-a[i]);}for(int i=0; i<n-m+1; i++){addedge(i+2,i+1+2,ar-al,0);}ans += mfmc(n-m+3,1,n-m+1+2);printf("%lld\n",ans);for(int i=1; i<=n; i++){if(NetFlow::e[2*i+2].w==0) {printf("E");} else {printf("S");}}puts("");return 0; }

總結(jié)

以上是生活随笔為你收集整理的Gym 101190D BZOJ 4842 Luogu P6967 LOJ #6071 [NEERC2016]Delight for a Cat (费用流)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。