洛谷P4003 無限之環 費用流

2022-09-01 09:39:10 字數 3838 閱讀 2602

曾經有一款流行的遊戲,叫做 infinity loop,先來簡單的介紹一下這個遊戲:

遊戲在乙個n×m

n×m的網格狀棋盤上進行,其中有些小方格中會有水管,水管可能在

格某些方向的邊界的中點有介面,所有水管的粗細都相同,所以如果兩個相鄰方格的

共邊界的中點都有接頭,那麼可以看作這兩個接頭互相連線。水管有以下15種形狀:

遊戲開始時,棋盤中水管可能存在漏水的地方。

形式化地:如果存在某個接頭,沒有和其它接頭相連線,那麼它就是乙個漏水的

地方。玩家可以進行一種操作:選定乙個含有非.直.線.型.水管的方格,將其中的水管繞方格

中心順時針或逆時針旋轉 90 度。

直線型水管是指左圖里中間一行的兩種水管。

現給出乙個初始局面,請問最少進行多少次操作可以使棋盤上不存在漏水的地方。

這道題可以把水流看成流量,旋轉次數看成費用,這樣就基本是乙個費用流的板子。

但是這道題建模還是比較難。主要有以下兩個問題:

如何保證每一條水管都有流量?

如何處理旋轉產生的費用?

我們先把每乙個點拆成五個點,分別是往上下左右流的邊和與原點匯點流的邊。姑且把後者稱作總點。

那麼為了保證每條邊都滿流,我們必須把點黑白染色,白點的總點連原點,然後原點連向上下左右;黑點的總點連匯點,然後從上下左右連總點。之後所有白點的上下左右點分別連黑點的上下左右點。

這樣我們就把整個圖建好了。其中我們把每一條邊拆成了兩個點之間分別的兩條邊,所以最終的流量會是我們建的兩點之間的邊的個數的一半。

那麼費用應該如何處理呢?

我們來分類討論一下。

注意:黑點與白點的連線正好完全相反。例如白點的連線為(x,

y)(x

,y),那麼黑點的連線為(y,

這種情況非常簡單。我們以水管朝上為例。那麼如果我們要讓水管朝左或者朝右,那麼只要花費1的費用即可。所以從上向左右分別連費用為1的邊,同理,從上向下連費用為2的邊。

由於題目要求直管不能旋轉,所以就不用再內部連任何的邊。

如果把這個水管順時針旋轉90°9

0°,那麼就相當於把左邊的水管放在了右邊,同理,逆時針就相當於把上面的水管放在了下面。

那麼就從上到下,從左到右分別連一條費用為1的邊。

此時如果旋轉180°1

80°的費用正好為2,和題目要求一致。

這種水管也很好理解,旋轉90°9

0°就相當於把左邊或右邊的水管轉移到下面。那麼就從左右向下連一條費用為1的邊。同理,從上到下連一條費用為2的邊。

這個轉了和沒轉沒有區別,所以就不用再內部連邊了。

注意除了上述連邊外,還有上下左右邊和總點的連邊、只要把這個水管原本的邊和總點連線即可。

主要還是靠理解,這個連邊在圖上不是很好畫,**就更加看不懂。。。

這是我至今為止連邊最長的費用流。

並且這道題用普通的eke

k會t,用zkw

zkw費用流就可以了。sp

fasp

fa最好加上slf

slf和l

llll

l優化。

#include

#include

#include

#include

#include

using

namespace std;

const

int n=

1000010

,inf=

1e9;

int n,m,s,t,maxflow,cnt,cost,tot=

1,head[n]

,dis[n]

;bool vis[n]

;struct edge

e[n]

;intu(

int x)

intd

(int x)

intl

(int x)

intr

(int x)

intread()

intpos

(int x)

if(a+b+c+d==3)

return4;

if(a+b+c+d==4)

return5;

}void

add(

int from,

int to,

int flow,

int cost)

bool

spfa()

q.pop_front()

; vis[u]=0

; sum-

=dis[u]

;for

(int i=head[u]

;~i;i=e[i]

.next)}}

}return dis[s]

}int

dfs(

int x,

int flow)

int used=0;

vis[x]=1

;for

(int i=head[x]

;~i;i=e[i]

.next)}}

return used;

}void

zkw()}

}int

main()

if(opt==2)

if(opt==3)

if(opt==4)

if(opt==5)

add(

u(x)

,x,1,0

),add(

d(x)

,x,1,0

),add(

l(x)

,x,1,0

),add(

r(x)

,x,1,0

),cnt+=4

;}else

if(opt==2)

if(opt==3)

if(opt==4)

if(opt==5)

add(x,

u(x),1

,0),

add(x,

d(x),1

,0),

add(x,

l(x),1

,0),

add(x,

r(x),1

,0),cnt+=4

;}if(

!((i+j)&1

))else

add(x,t,inf,0)

;}zkw();

if(maxflow*

2==cnt)

printf

("%d\n"

,cost)

;else

printf

("-1");

return0;

}

P4003 無限之環

題面自己看吧。std對於這種毒瘤的最小費用匹配問題,一般考慮網路費用流。對於每個水管的每乙個支管,有且僅有乙個其它方格上的水管的其中乙個支管與其相連,這樣就不會漏水了,也就是乙個水管的每個支管容量只能為 1 且都要滿流。由於我們要用網路流,又考慮到只有相鄰的兩個水管又可能產生流量,於是考慮將圖黑白染...

洛谷P4043 費用流

這題的建圖方式可以模擬洛谷p1251 我是由那個題才想到這麼建的,由於每條邊至少經過一次,我們又不清楚需要跑多少次,把邊看成點,點與匯點相連,可是我們又不知道最大流應該是多少,直接這麼連會發生錯誤。利用那道題的思想,每條邊最少需要一次,那麼就每條邊看做兩個點,點1和點2,點1有1的流量流向匯點,點2...

BZOJ5120無限之環 費用流

傳送門 題意 看原題吧,想不出比原題更好的描述了 solution 一開始思考過用網路流,但是想不出如何建圖,最後還是去看了題解qwq,建圖思路很妙啊,我們先把每個點拆成四個小點,分別對應上,下,左,右,然後對應每種水管在點內分別建圖 細節大家可以結合 思考一下 由於這是乙個二分圖 拆點之前 所以說...