日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

最大流总结

發(fā)布時(shí)間:2025/5/22 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最大流总结 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

準(zhǔn)備開(kāi)始學(xué)習(xí)最大流。模板是在網(wǎng)上抄的,感覺(jué)這個(gè)看起來(lái)比較優(yōu)雅。http://blog.csdn.net/d891320478/article/details/8424820

持續(xù)更新。

(hdu zoj poj vj 都掛了 還怎么刷題啊……)

(2016.9.6

sgu326. Perspective?

題意:一個(gè)小組有n個(gè)隊(duì)伍1~n,每場(chǎng)比賽一個(gè)隊(duì)伍贏,一個(gè)隊(duì)伍輸,現(xiàn)在已知每個(gè)隊(duì)伍i都已經(jīng)贏了Wi場(chǎng)比賽,同時(shí)知道每個(gè)隊(duì)伍還需要打Ri場(chǎng)比賽,包括組內(nèi)和組外,同時(shí)知道組內(nèi)還剩下的比賽場(chǎng)數(shù),Aij表示i和j還需要打幾場(chǎng)比賽,Aij=Aji,∑(j:1~n)Aij <= Ri

問(wèn)題是隊(duì)伍1能否成為小組獲勝場(chǎng)數(shù)最多的,可以并列第一。

>>首先讓隊(duì)伍1贏得所有的比賽,其他隊(duì)伍輸?shù)羲薪M外的比賽。然后建圖最大流。

/** 建一個(gè)源點(diǎn) 然后對(duì)于每一場(chǎng)比賽為一個(gè)點(diǎn) 從源點(diǎn)到比賽連邊,權(quán)值為比賽的總分?jǐn)?shù)* 比賽這個(gè)點(diǎn)和比賽的兩個(gè)隊(duì)伍分別連邊 權(quán)值大于等于比賽最大分?jǐn)?shù)即可* 每個(gè)隊(duì)伍到匯點(diǎn)連一條邊 權(quán)值應(yīng)為該隊(duì)伍和1隊(duì)分?jǐn)?shù)的差值(如果分?jǐn)?shù)大于1隊(duì),應(yīng)該直接輸出no* 走一遍最大流 如果答案是所有比賽的分?jǐn)?shù)和就可以滿足要求*/ #include <bits/stdc++.h>const int N = 1000; const int M = 1000000; const int INF = 1 << 30; struct Edge {int to, next, w; } edge[M]; int head[N], cntE; int src, sink; int pre[N], cur[N], dis[N], gap[N]; int que[N], open, tail; void addedge(int u, int v, int w) {edge[cntE].to = v;edge[cntE].w = w;edge[cntE].next = head[u];head[u] = cntE++;edge[cntE].to = u;edge[cntE].w = 0;edge[cntE].next = head[v];head[v] = cntE++; } void BFS() {int i, u, v;memset(gap, 0, sizeof(gap));memset(dis, -1, sizeof(dis));open = tail = 0;que[open] = sink;dis[sink] = 0;while (open <= tail) {u = que[open++];for (i = head[u]; i != -1; i = edge[i].next) {v = edge[i].to;if (edge[i].w != 0 || dis[v] != -1) continue;que[++tail] = v;++gap[dis[v] = dis[u] + 1];}} } int sap(int n) { //編號(hào)從1開(kāi)始 1~nint i, v, u, flow = 0, aug = INF;int flag;BFS();gap[0] = 1;for (i = 1; i <= n; i++) cur[i] = head[i];u = pre[src] = src;while (dis[src] < n) {flag = 0;for (int j = cur[u]; j != -1; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && dis[u] == dis[v] + 1) {flag = 1;if (edge[j].w < aug) aug = edge[j].w;pre[v] = u;u = v;if (u == sink) {flow += aug;while (u != src) {u = pre[u];edge[cur[u]].w -= aug;edge[cur[u] ^ 1].w += aug;}aug = INF;}break;}cur[u] = edge[j].next;}if (flag) continue;int mindis = n;for (int j = head[u]; j != -1; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && mindis > dis[v]) {mindis = dis[v];cur[u] = j;}}if (--gap[dis[u]] == 0) break;++gap[dis[u] = mindis + 1];u = pre[u];}return flow; }int w[N], r[N], a[N][N]; int main() {int n;while (~scanf("%d", &n)) {for (int i = 1; i <= n; ++i) scanf("%d", w+i);//每個(gè)隊(duì)伍已經(jīng)贏了多少場(chǎng)比賽for (int i = 1; i <= n; ++i) scanf("%d", r+i);//每個(gè)隊(duì)伍還可以打多少場(chǎng)比賽,包括本組和外組for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) scanf("%d", &a[i][j]);//本組剩余比賽情況w[1] += r[1]; //貪心 讓本隊(duì)全贏bool fg = false;for (int i = 2; i <= n; ++i) if (w[i] > w[1]) { fg = true; break; }if (fg) { puts("NO"); continue; }src = 1;int cnt = n+1;int sum = 0;cntE = 0;memset(head, -1, sizeof head);for (int i = 2; i <= n; ++i) for (int j = i; j <= n; ++j) {if (a[i][j] <= 0) continue;sum += a[i][j];addedge(src, cnt, a[i][j]);addedge(cnt, i, INF);addedge(cnt, j, INF);cnt++;}sink = cnt;for (int i = 2; i <= n; ++i) addedge(i, sink, w[1]-w[i]);if (sap(sink) == sum) puts("YES");else puts("NO");}return 0; } View Code

?(2016.9.7

codeforces546E-Soldier and Traveling

題意:有n個(gè)城市,m條無(wú)向圖,每個(gè)城市有ai的士兵,每個(gè)士兵可以走到相鄰的城市(只能走一步)或者原地不動(dòng)。問(wèn)能不能使得每個(gè)城市的士兵變成bi。

題解:首先有一個(gè)trick,就是sigma(ai)!=sigma(bi)的時(shí)候,記得輸出NO。

>>這題需要輸出點(diǎn)與點(diǎn)的轉(zhuǎn)移數(shù)量,在求最大流的過(guò)程中記錄

/* 把每個(gè)點(diǎn)拆成入點(diǎn)和出點(diǎn)* 從源點(diǎn)到每一個(gè)入點(diǎn)連一條 流量為該點(diǎn)的初始人數(shù)* 從每個(gè)點(diǎn)的入點(diǎn)到出點(diǎn)連一條邊 流量為該點(diǎn)的初始人數(shù)* 對(duì)于每條邊 從起點(diǎn)的入點(diǎn)到終點(diǎn)的出點(diǎn)連一條邊 流量為起點(diǎn)的初始人數(shù)* 每個(gè)出點(diǎn)連匯點(diǎn) 流量為該點(diǎn)的結(jié)束人數(shù)*/ #include <bits/stdc++.h>const int N = 1000; const int M = 1000000; const int INF = 1 << 30; struct Edge {int from, to, next, w; } edge[M]; int head[N], cntE; int src, sink; int pre[N], cur[N], dis[N], gap[N]; int que[N], open, tail;int ans[N][N];void addedge(int u, int v, int w) {edge[cntE].from = u;edge[cntE].to = v;edge[cntE].w = w;edge[cntE].next = head[u];head[u] = cntE++;edge[cntE].from = v;edge[cntE].to = u;edge[cntE].w = 0;edge[cntE].next = head[v];head[v] = cntE++; } void BFS() {int i, u, v;memset(gap, 0, sizeof(gap));memset(dis, -1, sizeof(dis));open = tail = 0;que[open] = sink;dis[sink] = 0;while (open <= tail) {u = que[open++];for (i = head[u]; i != -1; i = edge[i].next) {v = edge[i].to;if (edge[i].w != 0 || dis[v] != -1) continue;que[++tail] = v;++gap[dis[v] = dis[u] + 1];}} } int sap(int n) { //編號(hào)從1開(kāi)始 1~nint i, v, u, flow = 0, aug = INF;int flag;BFS();gap[0] = 1;for (i = 1; i <= n; i++) cur[i] = head[i];u = pre[src] = src;while (dis[src] < n) {flag = 0;for (int j = cur[u]; j != -1; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && dis[u] == dis[v] + 1) {flag = 1;if (edge[j].w < aug) aug = edge[j].w;pre[v] = u;u = v;if (u == sink) {flow += aug;while (u != src) {u = pre[u];edge[cur[u]].w -= aug;ans[edge[cur[u]].from][edge[cur[u]].to] += aug;edge[cur[u] ^ 1].w += aug;ans[edge[cur[u] ^ 1].from][edge[cur[u] ^ 1].to] -= aug;}aug = INF;}break;}cur[u] = edge[j].next;}if (flag) continue;int mindis = n;for (int j = head[u]; j != -1; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && mindis > dis[v]) {mindis = dis[v];cur[u] = j;}}if (--gap[dis[u]] == 0) break;++gap[dis[u] = mindis + 1];u = pre[u];}return flow; }int a[N], b[N]; int main() {int n, m, p, q;while (~scanf("%d%d", &n, &m)) {cntE = 0;memset(head, -1, sizeof head);memset(ans, 0, sizeof ans);src = 2 * n + 1, sink = 2 * n + 2;int sum = 0;for (int i = 1; i <= n; ++i) {scanf("%d", a+i); sum += a[i];addedge(src, i, a[i]);addedge(i, i+n, a[i]);}int sum2 = 0;for (int i = 1; i <= n; ++i) {scanf("%d", b+i); sum2 += b[i];addedge(i+n, sink, b[i]);}for (int i = 1; i <= m; ++i) {scanf("%d%d", &p, &q);addedge(p, q+n, a[p]);addedge(q, p+n, a[q]);}if (sum != sum2) {puts("NO");continue;}if (sap(sink) != sum) {puts("NO");} else {puts("YES");for (int i = 1; i <= n; ++i) {for (int j = 1; j <= n; ++j) {printf("%d%c", ans[i][j+n], j==n?'\n':' ');}}}}return 0; } View Code

codeforces653D-Delivery Bears

題意:有n個(gè)點(diǎn)m條有向邊,每個(gè)邊有一個(gè)容量,從這個(gè)邊走過(guò)的總重量不能超過(guò)這個(gè)容量,無(wú)重邊和自環(huán)?,F(xiàn)在有x只小熊,需要所有的熊從1出發(fā)走到n點(diǎn),每只熊攜帶相同質(zhì)量的貨物,問(wèn)最多能運(yùn)多少貨物。

>>開(kāi)始還以為容量需要小數(shù),后來(lái)發(fā)現(xiàn)想多了。。。精度什么的,1e-8wa,1e-10超時(shí),改成循環(huán)100遍竟然就對(duì)了。。。。為什么這么神奇呢。。。。

/* 首先二分每只熊所帶的貨物重量* 對(duì)于每條路徑,用路徑容量除以每只熊的重量就是這條路所能通過(guò)熊的數(shù)量* 因?yàn)樾軘y帶的重量會(huì)很小,容量又很大,所以可能爆int。。注意下。。* 要從源點(diǎn)到1建一個(gè)容量為x的邊* 當(dāng)最大流為x的時(shí)候 說(shuō)明所有熊都可以走到終點(diǎn)*/ #include <bits/stdc++.h> const int N = 1000; const int M = 1000000; const int INF = 1 << 30; struct Edge {int to, next, w; } edge[M]; int head[N], cntE; int src, sink; int pre[N], cur[N], dis[N], gap[N]; int que[N], open, tail;void addedge(int u, int v, int w) {edge[cntE].to = v;edge[cntE].w = w;edge[cntE].next = head[u];head[u] = cntE++;edge[cntE].to = u;edge[cntE].w = 0;edge[cntE].next = head[v];head[v] = cntE++; } void BFS() {int i, u, v;memset(gap, 0, sizeof(gap));memset(dis, -1, sizeof(dis));open = tail = 0;que[open] = sink;dis[sink] = 0;while (open <= tail) {u = que[open++];for (i = head[u]; i != -1; i = edge[i].next) {v = edge[i].to;if (edge[i].w != 0 || dis[v] != -1) continue;que[++tail] = v;++gap[dis[v] = dis[u] + 1];}} } int sap(int n) { //編號(hào)從1開(kāi)始 1~nint i, v, u, flow = 0, aug = INF;int flag;BFS();gap[0] = 1;for (i = 1; i <= n; i++) cur[i] = head[i];u = pre[src] = src;while (dis[src] < n) {flag = 0;for (int j = cur[u]; j != -1; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && dis[u] == dis[v] + 1) {flag = 1;if (edge[j].w < aug) aug = edge[j].w;pre[v] = u; u = v;if (u == sink) {flow += aug;while (u != src) {u = pre[u];edge[cur[u]].w -= aug;edge[cur[u] ^ 1].w += aug;}aug = INF;}break;}cur[u] = edge[j].next;}if (flag) continue;int mindis = n;for (int j = head[u]; j != -1; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && mindis > dis[v]) {mindis = dis[v];cur[u] = j;}}if (--gap[dis[u]] == 0) break;++gap[dis[u] = mindis + 1];u = pre[u];}return flow; }int a[N], b[N], c[N]; int main() {int n, m, x;scanf("%d%d%d", &n, &m, &x);double l = 0, r = 0;for (int i = 0; i < m; ++i) {scanf("%d%d%d", a+i, b+i, c+i);r += c[i];}src = n+1, sink = n;int cnt= 100;while (cnt--) {double mid = (l+r) / 2;memset(head, -1, sizeof head);cntE = 0;for (int i = 0; i < m; ++i) {int cap = std::min(floor(c[i]/mid), 1e8);addedge(a[i], b[i], cap);}addedge(src, 1, x);int tmp = sap(n+1);if (tmp == x) l = mid;else r = mid;}printf("%.10f\n", l*x); } View Code

?

codeforces510E-Fox And Dinner

題意:有n個(gè)狐貍1~n,每個(gè)狐貍ai歲?,F(xiàn)在需要將狐貍圍桌,一個(gè)桌子的狐貍數(shù)目要大于等于3,同時(shí)相鄰的兩只狐貍年齡加起來(lái)需要是一個(gè)質(zhì)數(shù)。問(wèn)分桌方式,不能分就輸出不可能。

>>開(kāi)始錯(cuò)的很離譜,發(fā)現(xiàn)判斷質(zhì)數(shù)寫(xiě)錯(cuò)了。。。后來(lái)又錯(cuò)的很奇怪,發(fā)現(xiàn)sap寫(xiě)錯(cuò)了。。。。

感覺(jué)這題比較難,根據(jù)奇偶構(gòu)圖第一次見(jiàn)到,學(xué)習(xí)了。。

/* 首先容易對(duì)于兩只狐貍,如果年齡和為質(zhì)數(shù),連邊* 因?yàn)橘|(zhì)數(shù)都是奇數(shù)(ai>=2)可知相鄰的狐貍年齡一定是一奇一偶* 那么一個(gè)桌子的奇數(shù)狐貍=偶數(shù)狐貍>=2* 從源點(diǎn)到每一個(gè)偶數(shù)建一個(gè)流量為2的邊* 每一個(gè)奇數(shù)到匯點(diǎn)建一個(gè)流量為2的邊* 然后年齡和為質(zhì)數(shù)的兩只狐貍之間建一條流量為1的邊* 然后跑最大流 如果流量為n就可以* 輸出比較麻煩。。看完建圖題解。。這里還想了半天Orz*/#include <bits/stdc++.h> const int N = 1000; const int M = 1000000; const int INF = 1 << 30; struct Edge {int from, to, next, w; } edge[M]; int head[N], cntE; int src, sink; int pre[N], cur[N], dis[N], gap[N]; int que[N], open, tail; int ans[N][N]; void addedge(int u, int v, int w) {edge[cntE].from = u;edge[cntE].to = v;edge[cntE].w = w;edge[cntE].next = head[u];head[u] = cntE++;edge[cntE].from = v;edge[cntE].to = u;edge[cntE].w = 0;edge[cntE].next = head[v];head[v] = cntE++; } void BFS() {int i, u, v;memset(gap, 0, sizeof(gap));memset(dis, -1, sizeof(dis));open = tail = 0;que[open] = sink;dis[sink] = 0;while (open <= tail) {u = que[open++];for (i = head[u]; ~i; i = edge[i].next) {v = edge[i].to;if (edge[i].w != 0 || dis[v] != -1) continue;que[++tail] = v;++gap[dis[v] = dis[u] + 1];}} } int sap(int n) { //編號(hào)從1開(kāi)始 1~nint i, v, u, flow = 0, aug = INF;int flag;BFS();gap[0] = 1;for (i = 1; i <= n; i++) cur[i] = head[i];u = pre[src] = src;while (dis[src] < n) {flag = 0;for (int j = cur[u]; ~j; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && dis[u] == dis[v] + 1) {flag = 1;if (edge[j].w < aug) aug = edge[j].w;pre[v] = u; u = v;if (u == sink) {flow += aug;while (u != src) {u = pre[u];edge[cur[u]].w -= aug;edge[cur[u] ^ 1].w += aug;ans[edge[cur[u]].from][edge[cur[u]].to] += aug;ans[edge[cur[u]^1].from][edge[cur[u]^1].to] -= aug;}aug = INF;}break;}cur[u] = edge[j].next;}if (flag) continue;int mindis = n;for (int j = head[u]; ~j; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && mindis > dis[v]) {mindis = dis[v];cur[u] = j;}}if (--gap[dis[u]] == 0) break;++gap[dis[u] = mindis + 1];u = pre[u];}return flow; }bool isprime(int x) {int limit = sqrt(x);for (int i = 2; i <= limit; ++i) if (x % i == 0) return false;return true; }int a[N]; int vis[N]; std::vector<int> G[N]; std::vector<int> ret[N];void dfs(int x, int u) {vis[u] = 1;ret[x].push_back(u);for (unsigned i = 0; i < G[u].size(); ++i) {int v = G[u][i];if (!vis[v]) { dfs(x, v); break;}} }int main() {memset(head, -1, sizeof head);cntE = 0;int n;scanf("%d", &n);for (int i = 1; i <= n; ++i) {scanf("%d", a+i);}src = n+1, sink = n+2;int odd = 0, even = 0;;for (int i = 1; i <= n; ++i)if (a[i] & 1) addedge(i, sink, 2), ++odd;else addedge(src, i, 2), ++even;if (odd != even) {puts("Impossible");return 0;}for (int i = 1; i <= n; ++i)for (int j = i+1; j <= n; ++j)if (isprime(a[i]+a[j])){if (a[i] & 1) addedge(j, i, 1);else addedge(i, j, 1);}if (sap(sink) != n) {puts("Impossible");} else {for (int i = 1; i <= n; ++i) {for (int j = 1; j <= n; ++j) {if (ans[i][j] == 1) G[i].push_back(j), G[j].push_back(i);}}int cnt = 0;for (int i = 1; i <= n; ++i) {if (!vis[i]) {++cnt;dfs(cnt, i);}}printf("%d\n", cnt);for (int i = 1; i <= cnt; ++i) {printf("%d", ret[i].size());for (int j = 0; j < ret[i].size(); ++j) printf(" %d", ret[i][j]);printf("\n");}}return 0; } View Code

?

(poj好了,趕緊來(lái)到poj的題壓壓驚= =)

poj2391Ombrophobic Bovines

題意:有f個(gè)農(nóng)場(chǎng),每個(gè)農(nóng)場(chǎng)有一個(gè)雨棚,每個(gè)農(nóng)場(chǎng)有field[i]頭牛,每個(gè)農(nóng)場(chǎng)的雨棚能裝shelter[i]頭牛,然后農(nóng)場(chǎng)之間有p條路徑,路徑可以通過(guò)無(wú)數(shù)頭牛,但是通過(guò)路徑需要花費(fèi)一些時(shí)間,問(wèn)所有牛都從農(nóng)場(chǎng)走到雨棚的最短時(shí)間。

>>這題比較上面的感覺(jué)比較簡(jiǎn)單了(wa了那么多次好意思說(shuō)

這竟然是我poj第100題。。。

/* 源點(diǎn)到每個(gè)農(nóng)場(chǎng)連農(nóng)場(chǎng)本來(lái)有的數(shù)量* 雨棚到匯點(diǎn)連雨棚能裝的數(shù)量* 二分時(shí)間 flody求出兩點(diǎn)之間最短時(shí)間* 任意兩點(diǎn)時(shí)間小于當(dāng)前二分需要時(shí)間 就把兩點(diǎn)的邊加入圖* 最大流等于牛的總數(shù)則符合條件 注意不能滿足輸出-1*/ #include <cstdio> #include <cstring> typedef long long ll; const int N = 500; const int M = N*N; const int INF = 1 << 30; const ll inf = 1LL<<50; struct Edge {int to, next, w; } edge[M]; int head[N], cntE; int src, sink; int pre[N], cur[N], dis[N], gap[N]; int que[N], open, tail;void addedge(int u, int v, int w) {edge[cntE].to = v;edge[cntE].w = w;edge[cntE].next = head[u];head[u] = cntE++;edge[cntE].to = u;edge[cntE].w = 0;edge[cntE].next = head[v];head[v] = cntE++; } void BFS() {int i, u, v;memset(gap, 0, sizeof(gap));memset(dis, -1, sizeof(dis));open = tail = 0;que[open] = sink;dis[sink] = 0;while (open <= tail) {u = que[open++];for (i = head[u]; ~i; i = edge[i].next) {v = edge[i].to;if (edge[i].w != 0 || dis[v] != -1) continue;que[++tail] = v;++gap[dis[v] = dis[u] + 1];}} } int sap(int n) { //編號(hào)從1開(kāi)始 1~nint i, v, u, flow = 0, aug = INF;int flag;BFS();gap[0] = 1;for (i = 1; i <= n; i++) cur[i] = head[i];u = pre[src] = src;while (dis[src] < n) {flag = 0;for (int j = cur[u]; ~j; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && dis[u] == dis[v] + 1) {flag = 1;if (edge[j].w < aug) aug = edge[j].w;pre[v] = u; u = v;if (u == sink) {flow += aug;while (u != src) {u = pre[u];edge[cur[u]].w -= aug;edge[cur[u] ^ 1].w += aug;}aug = INF;}break;}cur[u] = edge[j].next;}if (flag) continue;int mindis = n;for (int j = head[u]; ~j; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && mindis > dis[v]) {mindis = dis[v];cur[u] = j;}}if (--gap[dis[u]] == 0) break;++gap[dis[u] = mindis + 1];u = pre[u];}return flow; }ll d[N][N]; void floyd(int n) {for (int k = 1; k <= n; ++k)for (int i = 1; i <= n; ++i)for (int j = 1; j <= n; ++j)if (d[i][k] + d[k][j] < d[i][j])d[i][j] = d[i][k] + d[k][j]; }int field[N], shelter[N]; int main() {int f, p;while (~scanf("%d%d", &f, &p)) {int sum1 = 0, sum2 = 0;for (int i = 1; i <= f; ++i) {scanf("%d%d", &field[i], &shelter[i]);sum1 += field[i];sum2 += shelter[i];}for (int i = 1; i <= f; ++i) {for (int j = 1; j <= f; ++j) {d[i][j] = (i==j)?0:inf;}}ll l = 0, r = 0;int a, b, c;for (int i = 1; i <= p; ++i) {scanf("%d%d%d", &a, &b, &c);if (d[a][b] > c) d[b][a] = d[a][b] = c;r += c;}if (sum1 > sum2) {puts("-1");continue;}floyd(f);src = 2 * f + 1, sink = 2 * f + 2;ll ans = -1;while (l <= r) {ll mid = (l+r)>>1;memset(head, -1, sizeof head);cntE = 0;for (int i = 1; i <= f; ++i) {for (int j = 1; j <= f; ++j) {if (d[i][j]<=mid) addedge(i, j+f, INF);}}for (int i = 1; i <= f; ++i) {addedge(src, i, field[i]);addedge(i+f, sink, shelter[i]);}if (sap(sink) == sum1) {r = mid - 1;ans = mid;} else {l = mid + 1;}}printf("%lld\n", ans);}return 0; } View Code

?

(2016.9.8

hdu3605-Escape

題意:2012到了,大家要逃到別的星球去。一共有n個(gè)人,m個(gè)星球,每個(gè)人只能逃到某幾個(gè)星球,每個(gè)星球只能容納一定數(shù)量的人,問(wèn)能不能全部容納。(n<10^5,m<10)

>>第一道沒(méi)看題解的題QAQ

做了好幾道題,很容易想到的建圖是把源點(diǎn)到每個(gè)人連邊,每個(gè)人到能去的星球連容量為1的邊,每個(gè)星球到匯點(diǎn)連容量為星球容量的邊,然后跑最大流看容量是否為n就可以了。

這樣的超時(shí)的。。。

然后想到把星球狀壓,因?yàn)?0這個(gè)數(shù)字很容易讓人想到狀壓啊。。

想到狀壓之后一開(kāi)始我是把所有狀態(tài)連匯點(diǎn)的,但是wa了幾次想到有點(diǎn)星球會(huì)重復(fù)計(jì)算,于是又把每個(gè)星球和狀態(tài)連起來(lái)。

這樣邊數(shù)是10^5 點(diǎn)數(shù)也是10^5 反正是從10^6優(yōu)化了一下,最大流的復(fù)雜度也不是很好算,說(shuō)是O(E^2*V) ……

#include <bits/stdc++.h>using namespace std; typedef long long ll; const int N = 200005; const int M = 1000000; const int INF = 1 << 30; struct Edge {int from, to, next, w;//from一般用不到 } edge[M]; int head[N], cntE; int src, sink; int pre[N], cur[N], dis[N], gap[N]; int que[N], open, tail;void addedge(int u, int v, int w) {edge[cntE].from = u;edge[cntE].to = v;edge[cntE].w = w;edge[cntE].next = head[u];head[u] = cntE++;edge[cntE].from = v;edge[cntE].to = u;edge[cntE].w = 0;edge[cntE].next = head[v];head[v] = cntE++; } void BFS() {int i, u, v;memset(gap, 0, sizeof(gap));memset(dis, -1, sizeof(dis));open = tail = 0;que[open] = sink;dis[sink] = 0;while (open <= tail) {u = que[open++];for (i = head[u]; ~i; i = edge[i].next) {v = edge[i].to;if (edge[i].w != 0 || dis[v] != -1) continue;que[++tail] = v;++gap[dis[v] = dis[u] + 1];}} } int sap(int n) { //編號(hào)從1開(kāi)始 1~nint i, v, u, flow = 0, aug = INF;int flag;BFS();gap[0] = 1;for (i = 1; i <= n; i++) cur[i] = head[i];u = pre[src] = src;while (dis[src] < n) {flag = 0;for (int j = cur[u]; ~j; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && dis[u] == dis[v] + 1) {flag = 1;if (edge[j].w < aug) aug = edge[j].w;pre[v] = u; u = v;if (u == sink) {flow += aug;while (u != src) {u = pre[u];edge[cur[u]].w -= aug;edge[cur[u] ^ 1].w += aug;}aug = INF;}break;}cur[u] = edge[j].next;}if (flag) continue;int mindis = n;for (int j = head[u]; ~j; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && mindis > dis[v]) {mindis = dis[v];cur[u] = j;}}if (--gap[dis[u]] == 0) break;++gap[dis[u] = mindis + 1];u = pre[u];}return flow; }inline int read() {char ch = getchar();int data = 0;while (ch < '0' || ch > '9') ch = getchar();do {data = data * 10 + ch-'0';ch = getchar();} while (ch >= '0' && ch <= '9');return data; } int a[N]; int main() {int n, m;while (~scanf("%d%d", &n, &m)) {memset(head, -1, sizeof head);cntE = 0;int st = (1<<m);src = n+m+st; sink = src+1;for (int i = 1; i <= n; ++i) addedge(src, i, 1);for (int i = 1; i <= n; ++i) {int tmp = 0;for (int j = 0; j < m; ++j) if (read()) tmp += (1<<j);if (tmp != 0) addedge(i, tmp+n+m, 1);}for (int i = 0; i < m; ++i) addedge(n+i+1, sink, a[i]=read());for (int i = 1; i < st; ++i)for (int j = 0; j < m; ++j)if ((1<<j)&i) addedge(i+n+m, n+j+1, a[j]);if (sap(sink) == n) puts("YES");else puts("NO");}return 0; } View Code(1045MS)

又看了下別人的題解,Orz……直接源點(diǎn)連狀態(tài)就好了……明明可以是10^4的。。。。不過(guò)并沒(méi)有快很多。。。

#include <bits/stdc++.h>using namespace std; typedef long long ll; const int N = 200005; const int M = 1000000; const int INF = 1 << 30; struct Edge {int to, next, w; } edge[M]; int head[N], cntE; int src, sink; int pre[N], cur[N], dis[N], gap[N]; int que[N], open, tail;void addedge(int u, int v, int w) {edge[cntE].to = v;edge[cntE].w = w;edge[cntE].next = head[u];head[u] = cntE++;edge[cntE].to = u;edge[cntE].w = 0;edge[cntE].next = head[v];head[v] = cntE++; } void BFS() {int i, u, v;memset(gap, 0, sizeof(gap));memset(dis, -1, sizeof(dis));open = tail = 0;que[open] = sink;dis[sink] = 0;while (open <= tail) {u = que[open++];for (i = head[u]; ~i; i = edge[i].next) {v = edge[i].to;if (edge[i].w != 0 || dis[v] != -1) continue;que[++tail] = v;++gap[dis[v] = dis[u] + 1];}} } int sap(int n) { //編號(hào)從1開(kāi)始 1~nint i, v, u, flow = 0, aug = INF;int flag;BFS();gap[0] = 1;for (i = 1; i <= n; i++) cur[i] = head[i];u = pre[src] = src;while (dis[src] < n) {flag = 0;for (int j = cur[u]; ~j; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && dis[u] == dis[v] + 1) {flag = 1;if (edge[j].w < aug) aug = edge[j].w;pre[v] = u; u = v;if (u == sink) {flow += aug;while (u != src) {u = pre[u];edge[cur[u]].w -= aug;edge[cur[u] ^ 1].w += aug;}aug = INF;}break;}cur[u] = edge[j].next;}if (flag) continue;int mindis = n;for (int j = head[u]; ~j; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && mindis > dis[v]) {mindis = dis[v];cur[u] = j;}}if (--gap[dis[u]] == 0) break;++gap[dis[u] = mindis + 1];u = pre[u];}return flow; }inline int read() {char ch = getchar();int data = 0;while (ch < '0' || ch > '9') ch = getchar();do {data = data * 10 + ch-'0';ch = getchar();} while (ch >= '0' && ch <= '9');return data; } int a[N]; int v[N]; int main() {int n, m;while (~scanf("%d%d", &n, &m)) {memset(head, -1, sizeof head);memset(v, 0, sizeof v);cntE = 0;int st = (1<<m);src = m+st; sink = src+1;for (int i = 1; i <= n; ++i) {int tmp = 0;for (int j = 0; j < m; ++j) if (read()) tmp += (1<<j);v[tmp]++;}for (int i = 0; i < m; ++i) addedge(i+1, sink, a[i]=read());if (v[0]) {puts("NO");continue;}for (int i = 1; i < st; ++i) {addedge(src, i+m, v[i]);for (int j = 0; j < m; ++j)if ((1<<j)&i) addedge(i+m, j+1, a[j]);}if (sap(sink) == n) puts("YES");else puts("NO");}return 0; } View Code(1029ms)

?

hdu1569-方格取數(shù)(2)

這道題。。。要哭了真是。。。

題目中文的不說(shuō)了。。。把格子用(i+j)的奇偶分開(kāi)就可以變成二分圖,黑白棋盤(pán)染色。。同種顏色之間不可能相交。。

然后把相鄰的黑格和白格連起來(lái),就構(gòu)成了二分圖,然后求最大流。

二分圖的最大獨(dú)立集:在圖中選取最多的點(diǎn),使任意所選兩點(diǎn)均不相連
最大獨(dú)立數(shù) =? 頂點(diǎn)數(shù) —?最大匹配數(shù)

其實(shí)我一直都不理解這個(gè)。。這里。。最大獨(dú)立點(diǎn)權(quán)等于點(diǎn)權(quán)總和-最大點(diǎn)權(quán)匹配。。。

然后。。。我。。。把50*50算成了250。。我從懷疑模板到懷疑人生了。。。。我花了多長(zhǎng)時(shí)間反應(yīng)過(guò)來(lái)這個(gè)錯(cuò)誤啊。。。我提交了20多次啊。。。

#include <bits/stdc++.h> const int N = 2550; const int M = 1000000; const int INF = 1 << 30; struct Edge {int to, next, w; } edge[M]; int head[N], cntE; int src, sink; int pre[N], cur[N], dis[N], gap[N]; int que[N], open, tail;void addedge(int u, int v, int w) {edge[cntE].to = v;edge[cntE].w = w;edge[cntE].next = head[u];head[u] = cntE++;edge[cntE].to = u;edge[cntE].w = 0;edge[cntE].next = head[v];head[v] = cntE++; } void BFS() {int i, u, v;memset(gap, 0, sizeof(gap));memset(dis, -1, sizeof(dis));open = tail = 0;que[open] = sink;dis[sink] = 0;while (open <= tail) {u = que[open++];for (i = head[u]; ~i; i = edge[i].next) {v = edge[i].to;if (edge[i].w != 0 || dis[v] != -1) continue;que[++tail] = v;++gap[dis[v] = dis[u] + 1];}} } int sap(int n) { //編號(hào)從1開(kāi)始 1~nint i, v, u, flow = 0, aug = INF;int flag;BFS();gap[0] = 1;for (i = 1; i <= n; i++) cur[i] = head[i];u = pre[src] = src;while (dis[src] < n) {flag = 0;for (int j = cur[u]; ~j; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && dis[u] == dis[v] + 1) {flag = 1;if (edge[j].w < aug) aug = edge[j].w;pre[v] = u; u = v;if (u == sink) {flow += aug;while (u != src) {u = pre[u];edge[cur[u]].w -= aug;edge[cur[u] ^ 1].w += aug;}aug = INF;}break;}cur[u] = edge[j].next;}if (flag) continue;int mindis = n;for (int j = head[u]; ~j; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && mindis > dis[v]) {mindis = dis[v];cur[u] = j;}}if (--gap[dis[u]] == 0) break;++gap[dis[u] = mindis + 1];u = pre[u];}return flow; }int n, m; int a[100][100]; int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0}; int get(int i, int j) { return i*m+j+1; } int main() {while (~scanf("%d%d", &n, &m)) {memset(head, -1, sizeof head);cntE = 0;int sum = 0;for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {scanf("%d", &a[i][j]);sum += a[i][j];}}src = n*m+1, sink = n*m+2;for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {if ((i+j)&1) {addedge(get(i,j), sink, a[i][j]);} else {addedge(src, get(i,j), a[i][j]);for (int k = 0; k < 4; ++k) {int ni = i + dir[k][0];int nj = j + dir[k][1];if (ni<n&&ni>=0&&nj<m&&nj>=0) {addedge(get(i,j), get(ni,nj), INF);}}}}}printf("%d\n", sum-sap(sink));}} View Code

?

(2016.9.11

POJ2699-The Maximum Number of Strong Kings

題意:有n個(gè)人,每?jī)蓚€(gè)人之間都要進(jìn)行一次比賽。每場(chǎng)比賽只有一個(gè)人勝。當(dāng)一個(gè)人獲得最多的獲勝場(chǎng)數(shù)或者他打敗了所有獲勝場(chǎng)數(shù)比他多的人,他就是king,現(xiàn)在給出每個(gè)人的獲勝次數(shù),求最多有多少個(gè)king。n<=10。

題解:很容易想到獲勝場(chǎng)數(shù)越多的人越容易成為king,于是我一直在想怎么貪心建圖。。。。后來(lái)還是不會(huì)。。。查題解才意識(shí)到n這么小,枚舉king的數(shù)量就可以了。。。。(暴力枚舉所有情況都可以。。。)一個(gè)trick就是獲勝局?jǐn)?shù)相等的情況。。

初始化的時(shí)候出錯(cuò)了。。。。點(diǎn)數(shù)不是n。。。。。這個(gè)要記住。。。。

讀入有坑。。。

#include <cstring> #include <vector> #include <cstdio> #include <queue>const int N = 200; const int INF = 1<<30; struct Edge { int to, cap, rev; }; std::vector<Edge> G[N]; int level[N]; int iter[N];void addedge(int u, int v, int cap) {G[u].push_back(Edge{v, cap, G[v].size()});G[v].push_back(Edge{u, 0, G[u].size()-1}); }void bfs(int s) {memset(level, -1, sizeof level);std::queue<int> que;level[s] = 0;que.push(s);while (que.size()) {int v = que.front(); que.pop();for (int i = 0; i < G[v].size(); ++i) {Edge &e = G[v][i];if (e.cap > 0 && level[e.to] < 0) {level[e.to] = level[v] + 1;que.push(e.to);}}} }int dfs(int v, int t, int f) {if (v == t) return f;for (int &i = iter[v]; i < G[v].size(); ++i) {Edge &e = G[v][i];if (e.cap > 0 && level[e.to] > level[v]) {int d = dfs(e.to, t, std::min(f, e.cap));if (d > 0) {e.cap -= d;G[e.to][e.rev].cap += d;return d;}}}return 0; }int maxflow(int s, int t) {int flow = 0;for (; ;) {bfs(s);if (level[t] < 0) return flow;memset(iter, 0, sizeof iter);int f;while ((f = dfs(s, t, INF)) > 0) flow += f;}return flow; }int a[N]; void input(int &n) {char str[100];gets(str);int val = 0, len = strlen(str);for (int i = 0; i < len; i++) {if (str[i] >= '0' && str[i] <= '9') {val = val * 10 + str[i] - '0';if (i == len-1 || str[i+1] < '0' || str[i+1] > '9')a[++n] = val, val = 0;}} }int main() {int T;scanf("%d", &T); getchar();while (T--) {int n = 0;int sum = 0;int maxn = 0;input(n);for(int i = 1; i <= n; ++i) {sum += a[i];maxn = std::max(maxn, a[i]);}//for (int i =1; i <= n; ++i) printf("%d ", a[i]); printf("%d %d\n", maxn, sum);int ans = 0; int src = 0; int sink = n*n+n+1;for (int k = 1; k <= n; ++k) {for (int i = 0; i <= sink; ++i) G[i].clear();for (int i = 1; i <= n; ++i) {for (int j = i+1; j <= n; ++j) {int tmp = i * n + j;addedge(src, tmp, 1);addedge(tmp, i, 1);if (i < k || a[i] == a[j]) addedge(tmp, j, 1);}}for (int i = 1; i <= n; ++i) addedge(i, sink, a[i]);int tmp = maxflow(src, sink);if (tmp >= sum) {ans = n-k+1;break;}}printf("%d\n", ans);}return 0; } View Code

?

POJ 3281--Dining

題意:有f種食物d中飲料和n頭牛,每個(gè)牛要吃食物和飲料,每個(gè)牛對(duì)食物和飲料都有要求,只吃某幾種。。。而一種食物和一種飲料只能被一只牛吃,現(xiàn)在求最多有多少只牛既能吃到食物又能喝到飲料。。

人不如牛啊。。。。。。

一直在想怎么分解組合食物,然而正解是分解牛。。。突然發(fā)現(xiàn)數(shù)組開(kāi)大了會(huì)慢好多Orz。。。。

src--food--cow_food--cow_drink--drink--sink

#include <cstring> #include <vector> #include <cstdio> #include <queue>const int N = 1000; const int M = 1000000; const int INF = 1 << 30; struct Edge {int from, to, next, w;//from一般用不到 } edge[M]; int head[N], cntE; int src, sink; int pre[N], cur[N], dis[N], gap[N]; int que[N], open, tail;void addedge(int u, int v, int w) {edge[cntE].from = u;edge[cntE].to = v;edge[cntE].w = w;edge[cntE].next = head[u];head[u] = cntE++;edge[cntE].from = v;edge[cntE].to = u;edge[cntE].w = 0;edge[cntE].next = head[v];head[v] = cntE++; } void BFS() {int i, u, v;memset(gap, 0, sizeof(gap));memset(dis, -1, sizeof(dis));open = tail = 0;que[open] = sink;dis[sink] = 0;while (open <= tail) {u = que[open++];for (i = head[u]; ~i; i = edge[i].next) {v = edge[i].to;if (edge[i].w != 0 || dis[v] != -1) continue;que[++tail] = v;++gap[dis[v] = dis[u] + 1];}} } int sap(int n) { //編號(hào)從1開(kāi)始 1~nint i, v, u, flow = 0, aug = INF;int flag;BFS();gap[0] = 1;for (i = 1; i <= n; i++) cur[i] = head[i];u = pre[src] = src;while (dis[src] < n) {flag = 0;for (int j = cur[u]; ~j; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && dis[u] == dis[v] + 1) {flag = 1;if (edge[j].w < aug) aug = edge[j].w;pre[v] = u; u = v;if (u == sink) {flow += aug;while (u != src) {u = pre[u];edge[cur[u]].w -= aug;edge[cur[u] ^ 1].w += aug;}aug = INF;}break;}cur[u] = edge[j].next;}if (flag) continue;int mindis = n;for (int j = head[u]; ~j; j = edge[j].next) {v = edge[j].to;if (edge[j].w > 0 && mindis > dis[v]) {mindis = dis[v];cur[u] = j;}}if (--gap[dis[u]] == 0) break;++gap[dis[u] = mindis + 1];u = pre[u];}return flow; }// src--food--cow_food--cow_drink--drink--sink int main() {int n, f, d;scanf("%d%d%d", &n, &f, &d);src = 2*n+f+d+1;sink = 2*n + f + d + 2;memset(head, -1, sizeof head);cntE = 0;for (int i = 1; i <= f; ++i) addedge(src, i, 1);for (int i = 1; i <= d; ++i) addedge(f+n*2+i, sink, 1);int fi, di;int a, b;for (int k = 1; k <= n; ++k) {scanf("%d%d", &fi, &di);addedge(f+k, f+n+k, 1);for (int i = 0; i < fi; ++i) {scanf("%d", &a);addedge(a, f+k, 1);}for (int i = 0; i < di; ++i) {scanf("%d", &b);addedge(f+n+k, n*2+f+b, 1);}}printf("%d\n", sap(sink));return 0; } View Code

?

(2016.9.12

http://blog.csdn.net/hnust_xiehonghao/article/details/11050217

題意:有一條東西向流淌的河,寬為 W,河中有 N 塊石頭,每塊石頭的坐標(biāo)(Xi, Yi)和最大承受人數(shù) Ci 已知?,F(xiàn)在有 M 個(gè)游客在河的南岸,他們想穿越這條河流,但是每個(gè)人每次最遠(yuǎn)只能跳 D 米,每跳一次耗時(shí) 1 秒。問(wèn)他們能否全部穿越這條河流,如果能,最少需要多長(zhǎng)時(shí)間。 <= N <= 50, 0 < M <= 50, 0 <= D <= 1000, 0 < W(0<= 1000, 0 < Xi < 1000, 0 < Yi < W, 0 <= Ci <= 1000)。剛看完這題,想當(dāng)然的認(rèn)為它是一道最小費(fèi)用流問(wèn)題。但是當(dāng)WA之后我才明白,這題并不是去求一個(gè)給定網(wǎng)絡(luò)的最大流,而是計(jì)算這個(gè)網(wǎng)絡(luò)隨著時(shí)間 推移每次能夠留出多少流量。我們通過(guò)枚舉時(shí)間的方式來(lái)決定在什么時(shí)刻能夠把所有的人全部送到對(duì)岸。注意人是可以從河這岸的任意x坐標(biāo)出發(fā)的。(開(kāi)始人都在X軸上.對(duì)岸可以看為 Y = W的一條直線)

>>見(jiàn)了鬼了 CE了好多次 同樣的代碼 一會(huì)CE 一會(huì)運(yùn)行 。。。。

這題應(yīng)該是我做的這些題里面最難的了=。=

這個(gè)分解的竟然是時(shí)間。。。因?yàn)閚和m都非常小,又可以知道時(shí)間最多花費(fèi)n+m,否則過(guò)不去,所以枚舉需要的時(shí)間就可以了。。。

每增加單位時(shí)間,就增加通往新時(shí)間的邊。。。。

因?yàn)槊總€(gè)點(diǎn)都有流量限制,所以還要拆點(diǎn)。。。。

一直過(guò)不了樣例。。。。照著別人的代碼一點(diǎn)一點(diǎn)改還是不對(duì)。。。。后來(lái)終于意識(shí)到每一次的流量是要相加的(別人的dinic貌似不是這樣的?。。。)。。。反正坑了好久。。

#include <cstring> #include <vector> #include <cstdio> #include <queue> using namespace std; typedef long long ll;int Scan() {int res = 0, flag = 0;char ch;if((ch = getchar()) == '-') flag = 1;else if(ch >= '0' && ch <= '9') res = ch - '0';while((ch = getchar()) >= '0' && ch <= '9')res = res * 10 + (ch - '0');return flag ? -res : res; }const int N = 10010; const int INF = 1<<30; struct Edge { int to, cap, rev; }; std::vector<Edge> G[N]; int level[N]; int iter[N];void addedge(int u, int v, int cap) {G[u].push_back((Edge){v, cap, G[v].size()});G[v].push_back((Edge){u, 0, G[u].size()-1}); }void bfs(int s) {memset(level, -1, sizeof level);std::queue<int> que;level[s] = 0;que.push(s);while (que.size()) {int v = que.front(); que.pop();for (unsigned i = 0; i < G[v].size(); ++i) {Edge &e = G[v][i];if (e.cap > 0 && level[e.to] < 0) {level[e.to] = level[v] + 1;que.push(e.to);}}} }int dfs(int v, int t, int f) {if (v == t) return f;for (int &i = iter[v]; i < (int)G[v].size(); ++i) {Edge &e = G[v][i];if (e.cap > 0 && level[e.to] > level[v]) {int d = dfs(e.to, t, std::min(f, e.cap));if (d > 0) {e.cap -= d;G[e.to][e.rev].cap += d;return d;}}}return 0; }int maxflow(int s, int t) {int flow = 0;for (; ;) {bfs(s);if (level[t] < 0) return flow;memset(iter, 0, sizeof iter);int f;while ((f = dfs(s, t, INF)) > 0) flow += f;}return flow; }int x[55], y[55], c[55]; int dis[55][55]; int n, m, d, w;int cal(int a, int b) { return (x[a]-x[b])*(x[a]-x[b]) + (y[a]-y[b])*(y[a]-y[b]); } int get1(int x, int t) { return (t-1) * n + x + 1; } int get2(int x, int t) { return 5000 + (t-1) * n + x + 1; }int main() {n = Scan(); m = Scan(); d = Scan(); w = Scan();for (int i = 1; i <= n; ++i) x[i] = Scan(), y[i] = Scan(), c[i] = Scan();if (w <= d) { puts("1"); return 0; }for (int i = 1; i <= n; ++i)for (int j = 1; j <= n; ++j)dis[i][j] = (cal(i, j) <= d*d) ? 1 : 0;int ans = 0;int src = 0, sink = 1;for (int t = 1; t <= n+m; ++t) {for (int i = 1; i <= n; ++i) {if (y[i] <= d) addedge(src, get1(i, t), INF);if (y[i]+d >= w) addedge(get2(i,t), sink, INF);addedge(get1(i, t), get2(i, t), c[i]);for (int j = 1; j <= n; ++j)if (dis[i][j]) addedge(get2(i, t), get1(j, t+1), INF);}ans += maxflow(src, sink);if (ans >= m) {printf("%d\n", t+1);break;}}if (ans < m) puts("IMPOSSIBLE");return 0; } View Code

?

先刷到這,有時(shí)間還要做套最小割的題= =

轉(zhuǎn)載于:https://www.cnblogs.com/wenruo/p/5847034.html

總結(jié)

以上是生活随笔為你收集整理的最大流总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。