HDU 3605 Escape 最大流,狀態壓縮

2022-05-21 10:24:10 字數 1370 閱讀 5303

地球上有$n(1\leq n \leq 100000)$個人需要移居到$m(1\leq m \leq 10)$個外星球上,每個人只有特定的若干個外星球可供選擇,每個外星球有接受移居的人數上限,問能否讓所有人移居成功。

由於$n$的範圍有$1e5$,直接建圖的話邊可能達到$1e6$條,跑最大流會超時。

考慮到$m$最大只有$10$,每個人可選擇的若干星球最多只有$2^$種可能的狀態,所以實際上當$n$比較大時,很多人可選擇的若干個星球是一樣的。我們可以用二進位制狀態壓縮來表示一種可選星球的狀態,統計出這種狀態的人數,以狀態為結點,就不用每個人用乙個結點表示。

用$s$和$t$分別表示源點、匯點,$(始點,終點,容量)$表示一條邊,建圖如下:

對於每乙個狀態,連邊$(s,狀態,可選星球是這個狀態的人數)$;

對於乙個狀態中可選擇的每乙個星球,連邊$(狀態,星球,無窮大)$;

對於每乙個星球,連邊$(星球,t,星球的人數上限)$。

最大流就是能成功移居的最大人數。

#include #include 

#include

#include

using

std::queue;

const

int inf = 0x3f3f3f3f, n = 2000, m = 30000

;int

head[n], d[n], cnt[n];

ints, t, tot, maxflow;

struct

edge

edge[m];

queue

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

z) bool

bfs() }}

return

false;}

int dinic(int x, int

flow)

}return flow -rest;

}void init(int

n) int

main()

if (!cnt[sta]) for (int j = m - 1; j >= 0; j--)

cnt[sta]++;

}for (int i = 0; i < 1024; i++) if

(cnt[i]) add(s, i, cnt[i]);

for (int i = 0, num; i < m; i++)

while (bfs()) maxflow +=dinic(s, inf);

if (maxflow >= n) puts("

yes"

);

else puts("no"

); }

return0;

}

view code

HDU 3605 Escape 最大流,狀壓

最大流,n比較大,但是m只有10,所以對應的人的狀態最多有2 m種,因此可以對人進行歸類,那樣n的資料量就只有1024了,求最大流 g 交會超時 要用c include include include include include define maxn 1100 define maxe 2100...

最大流 縮點 HDU 3605 Escape

有n個人,m個星球。每個人都對不同的星球有自己的喜好,每個星球都有自己的容量。問能否讓所有的人都呆在自己喜歡的星球裡。1 n 100000 m 1 m 10 以為是套模板的題,一直tle,mle。看了大佬的 才明白這題需要縮點。因為最多有10個星球,所以最多有 include include inc...

HDU 3605 Escape (最大流 縮點)

題意 給你n個人,m個星球,每個人對這m個星球的都有一定的適應能力,每個星球都有一定的容納量,問能否讓所有的人在星球上生存。剛開始做的時候一直tle 不知道為什麼,改著改著發現建圖的時候,添了很多邊,這樣跑最大流非常慢,看了網上的思路才知道要縮點,因為星球最多才有10個,所以把每個星球適合住的人數存...