bzoj 4261 建設遊樂場 費用流

2022-02-27 09:02:19 字數 2570 閱讀 2555

現在有一大塊土地,可以看成n*m的方格。在這塊土地上,有些格仔內是崎嶇的山地,無法建造任何東西;其他格仔都是平原。現在打算在這塊土地上建設乙個遊樂園。遊樂園由若干條閉合的過山車軌道組成,每個平原格仔都要鋪一截軌道,為下列 6 種型別中的一種:

(每張圖表示一塊平原格仔,圖內網格線為輔助線,無實際意義。)

其中前 2 種為直軌道,後 4 種為彎軌道。顯然對遊客來說,彎軌道更加刺激。

由於每塊格仔風景各不相同,經過一番研究,現給了n*m個方格中的每個格仔乙個評估值,意義為:如果該格仔修建彎軌道,會給遊客們帶來多少的愉悅值。現需要一名設計師,幫他設計一種最優的軌道建設方案,使所有格仔給遊客們帶來的愉悅值之和盡量大。(如果沒有合法方案,輸出 -1)

n<=150,m<=30,vi,j<=100

乍一看沒有什麼思路.

但仔細觀察一下可以通過直覺感覺出來是網路流。

(oi人的直覺)

在棋盤問題上應用網路流演算法,經典的就是黑白染色。

所以我們將棋盤黑白染色。

然後我們考慮怎樣構造方案:

其中每個加粗邊的流量是2,然後我們判斷一下最大流是否為節點數即可.

那麼對於轉彎時付出的代價要怎麼計算?

我們還是在上述的模型中進行改進,我們對邊賦以權值。

然後考慮把點拆成和x方向的白點進行連線與和y方向的白點進行連線兩種點。

然後再加乙個點來控制到達這兩個點的總流量為2。

然後就很明朗了,我們只要完成這麼乙個限制:如果流量分別走了兩邊,就獲得權值。

但是經過仔細思考後並不能完成這麼乙個限制...

所以考慮轉化一下。我們知道上述條件等價於:如果流量都走了同一邊,就無法獲得權值.

這個限制是我們可以簡單完成的,只要利用凸費用流的性質即可.

所以跑最小費用最大流即可.

#include #include #include using namespace std;

typedef long long ll;

inline void read(int &x)

#define rg register int

#define rep(i,a,b) for(rg i=(a);i<=(b);++i)

#define per(i,a,b) for(rg i=(a);i>=(b);--i)

const int maxn = 160;

const int maxm = 36;

const int maxnode = 3*maxn*maxm;

const int maxedge = maxnode*4;

struct edgeg[maxedge<<1];

int head[maxnode],cnt = 1;

inline void add(int u,int v,int c,int d)

inline void insert(int u,int v,int c,int d)

#define v g[i].to

const int lim = maxnode<<1;

int q[lim+10],dis[maxnode],p[maxnode];

int flow[maxnode];

int l,r,s,t,fl;ll ans;bool inq[maxnode];

int nodecnt;

const int inf = 0x3f3f3f3f;

inline bool spfa()

l = 0;r = -1;q[++r % lim] = s;

inq[s] = true;flow[s] = inf;

dis[s] = 0;

while(l <= r)

}}inq[u] = false;

}if(dis[t] == inf) return false;

ans += 1ll*flow[t]*dis[t];

fl += flow[t];

for(rg u = t;u != s;u = g[p[u]^1].to)

g[p[u]].cap -= flow[t],g[p[u]^1].cap += flow[t];

return true;

}#undef v

int idx[maxn][maxm],idy[maxn][maxm],id[maxn][maxm];

int main()

} }

ll tot = 0;

s = ++ nodecnt;t = ++ nodecnt;

rep(i,1,n)else

if((i+j)&1^1)

} }

while(spfa());

if(fl != nodecnt / 3)

printf("%lld\n",tot - ans);

return 0;

}

BZOJ4261 建設遊樂場

將圖黑白染色,每個點拆成兩個點,分別表示水平和豎直方向,再增加乙個點以控制流量,那麼每個格仔都需要找兩個方向去連線。s 到每個黑點的控制點連邊,流量 2 費用 0 控制點向兩個方向的點各連兩條邊,第一條流量 1 費用 0 第二條流量 1 費用 w 然後兩個方向的點分別向對應白點連邊,流量 1 費用 ...

遊樂場 題解

據新聞報道,orz教主在太平洋 建了乙個大遊樂園,其中有許多小島,每個小島上有且僅有乙個遊樂設施,有的小島與小島之間有海底隧道連線,而有的沒有,乙個遊樂設施對乙個人只開放一次,花的錢與得到的快樂值成正比。一開始,你可以選擇被空投到任意乙個小島。當你想離開遊樂園時,你可以打 叫飛機來接,但不能再次被空...

hdu 2015新生賽 遊樂場

problem description 小時候,因為家裡經濟困難,小明從未去過遊樂場,所以直到現在,他還心存遺憾。最近,杭州剛建了一座遊樂場,為了彌補兒時的遺憾,小明帶了一筆錢迫不及待地要去體驗一番。由於是第一次來到這種地方,小明也不知哪些專案比較好玩,因此他想體驗盡可能多的專案。來之前,小明還向朋...