清華集訓 2017 無限之環

2022-02-05 14:07:02 字數 3893 閱讀 4948

無限之wa

本題如果知道是網路流的話,其實建圖不算特別神奇,但是比較麻煩。

資料範圍過大,插頭dp不能處理,而且是乙個網格圖,考慮網路流。

先看是不是二分圖?

每個格仔只會和相鄰四個格仔發生關係

所以,黑白染色正好。

i+j為偶數左部點,i+j為奇數右部點

不漏水是什麼?

每個管道的四個口都能和別的接好。

s向左,右向t連口數的容量,費用為0的邊

考慮怎麼能把左右連在一起。

考慮要上下左右四個方向匹配,那麼必然還要拆點(但是這些點之間是並列關係)。

每個本點向四個分點之間考慮連邊(在這裡考慮旋轉以及費用)

考慮通過流量流過來表示選擇旋轉與否,恰當的邊賦恰當的值。

sz=1:

自己方向是(1,0)相鄰方向(1,1),對面(1,2)

sz=2:

直線型:自己方向(1,0),另外兩個不連(因為不能轉),

非直線型:自己兩個方向(1,0),每個自己方向+2(-2),連(1,1),(手動模擬一下這樣選擇的四種流法對應四種旋轉的位置)

sz=3:

自己(1,0),剩下乙個0位置,距離為1的向它連(1,1),距離為2的向它連(1,2)

sz=4

四個方向(1,0);

(注意,右邊的單向邊方向和左邊的完全相反)

然後左右分點之間相鄰的關係上下,左右,下上,右左,左分點連到對應的右分點。

然後跑最小費用最大流。

至於-1

先判斷黑格口數是不是等於白格口數

然後如果最大流不是口數(滿流)的話,就-1

(其實資料沒有-1的點23333~~~)

這樣,一條流的意義是什麼?左邊的某個口和右邊的某個口,通過旋轉或者不旋轉連線在了一起,同時兩個管道的需求都少了1

由於所有邊的流量都是1(除了和st連的),所以每個口只會流出1流,減少1的需求,

如果最後滿流

那麼意味著,所有的口都滿足了自己的需求,即每個口都連上了。而且每個流都合法。

出錯點:

1.陣列開小了。。。。has[4],四位二進位制數,少開一位。。。(這個導致開o2之後超級厭氧,全部輸出-1wa掉,一定程度上轉移了查錯重心。。。)

2.提取四位二進位制數的時候,習慣性地寫成了while(tmp) has[++tot]=tmp%2,tmp>>=1;然鵝,最高位是0的話,沒有提取完4位就break了。而且has沒有memset,高位就存上了之前可能的1.。。。。導致wa死。。

其實開始找規律一點沒錯。。。。但是由於while高位0的鍋,以為找錯了,,,最後還打了暴力判斷。。。。

**:(得開o2)

#pragma gcc optimize(2)

#pragma gcc optimize(3)

#pragma gcc optimize("ofast")#include

#define il inline

#define reg register int

#define numb (ch^'0')

using

namespace

std;

typedef

long

long

ll;il

void rd(int &x)

namespace

miraclee[(

5*n+4*n+n*6)*2

];int hd[5*n],cnt=1

;void add(int x,int y,int w,int

v)int incf[5*n],dis[5*n];

int pre[5*n];

bool vis[5*n];

queue

q;bool

spfa()

} }}

if(dis[t]==inf) return

false

;

return

true;}

intans,maxflow;

void

upda()

ans+=incf[t]*dis[t];

maxflow+=incf[t];

//cout<<" ans "<}

int has[10

],tot;

intmp[n][n];

intsz[n];

int num(int x,int y,int k)

intmain()

int le=0,ri=0

;

for(reg i=1;i<=n;++i)

}if(le!=ri)

for(reg i=1;i<=n;++i)

int now=num(i,j,5

); tot=sz[mp[i][j]];

if((i+j)%2==0

)

case1:

add(now,num(i,j,pos),

1,0);

add(now,num(i,j,pos%4+1),1,1

); add(now,num(i,j,pos==1?4:pos-1),1,1

); add(now,num(i,j,(pos+2

<=4)?pos+2:pos-2),1,2

);

break

; }

case2:

}else}}

break

; }

case3:

else

}break

; }

case4:

break

; }}}

else

case1:

add(num(i,j,pos),now,

1,0);

add(num(i,j,pos%4+1),now,1,1

); add(num(i,j,pos==1?4:pos-1),now,1,1

); add(num(i,j,(pos+2

<=4)?pos+2:pos-2),now,1,2

);

break

; }

case2:

}else}}

break

; }

case3:

else

}break

; }

case4:

break

; }}}

if((i+j)%2==0

) }

}while

(spfa()) upda();

//cout<<" maxflow "printf("%d

",ans);

return0;

}}signed main()

/*author: *miracle*

date: 2018/12/14 21:08:15

*/

總結:這個題的突破口的話,

發現插頭dp不行,那麼網格圖,可能就是網路流(資料範圍也支援)

黑白染色可以。那麼考慮最終合法的結果是什麼意義。然後處理好旋轉連邊。

(發現沒有,直線型為什麼不能轉?因為這樣會同時轉2個點!網路流沒辦法處理這種旋轉(除非你大力討論))

清華集訓 2017 無限之環(費用流)

清華集訓 2017 無限之環 費用流神題。對於每乙個方格延伸出去的每一根水管,有且僅有乙個其他方格延伸出的水管與之相連,這樣就不會漏水。即 每根水管的容量為 1 1 且必須滿流。然而即使產生了最優情況,整個管網也不一定是一整個聯通塊,而可能被分成若干塊。因此,我們要對每個格點染色,相鄰的兩個格點,乙...

清華集訓2017模擬 ces

首先把用tajan把橋邊全部找出來,橋邊會把圖分成若干個雙聯通分量。把每個雙聯通分量並成乙個點,橋邊作為邊,這會構成一棵樹。顯然,對於每個詢問加k條邊最多能去掉多少條橋邊,就是用k條簡單路徑去覆蓋這棵樹,最多能覆蓋多少條邊。有乙個很優的貪心,把k按1 q做,每次找到樹的直徑,答案加上直徑的長度,把直...

清華集訓2017滾粗記

很早就到了,然後就被眾人教育,晚上連營ak殺被wzd yql教育,去找wyy換衣服又被wyy和dwj教育。虛心接受教育之後就回去了。考得最崩的一天。開場看完題發現t1是個原題加強,t2只會狀壓的部分分,t3是個裸分塊但是要寫挺久的,於是決定先開t1。開了t1半個小時之後發現毫無思路,式子並不能像原題...