地球上有$n(1\leq n \leq 100000)$個人需要移居到$m(1\leq m \leq 10)$個外星球上,每個人只有特定的若干個外星球可供選擇,每個外星球有接受移居的人數上限,問能否讓所有人移居成功。
由於$n$的範圍有$1e5$,直接建圖的話邊可能達到$1e6$條,跑最大流會超時。
考慮到$m$最大只有$10$,每個人可選擇的若干星球最多只有$2^$種可能的狀態,所以實際上當$n$比較大時,很多人可選擇的若干個星球是一樣的。我們可以用二進位制狀態壓縮來表示一種可選星球的狀態,統計出這種狀態的人數,以狀態為結點,就不用每個人用乙個結點表示。
用$s$和$t$分別表示源點、匯點,$(始點,終點,容量)$表示一條邊,建圖如下:
對於每乙個狀態,連邊$(s,狀態,可選星球是這個狀態的人數)$;
對於乙個狀態中可選擇的每乙個星球,連邊$(狀態,星球,無窮大)$;
對於每乙個星球,連邊$(星球,t,星球的人數上限)$。
最大流就是能成功移居的最大人數。
#include #includeview code#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;
}
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個,所以把每個星球適合住的人數存...