Idea: At the beginning, I thought about how to build a picture. The source point connects to all the food, food, cattle, drinks, and drinks. All the traffic is 1. however, after the figure is created, WA is finished. It turns out that a cow can only match a group of food and drinks, so the ox has to be split, and the ox has to be connected, with a traffic of 1 to ensure a single matching of food and drinks.
Code of the single path of the dinic in the adjacent matrix:
# Include <iostream> # include <cstdio> # include <cstring> # include <algorithm> # include <map> # include <queue> # include <set> # include <cmath> # include <bitset> # define MEM (, b) memset (a, B, sizeof (A) # define lson I <1, L, mid # define rson I <1 | 1, Mid + 1, R # define llson j <1, L, mid # define rrson j <1 | 1, Mid + 1, R # define INF 0x7fffffff # define maxn 20005 typedef long ll; typedef unsigned long ull; using namespace STD; int n, m, D [maxn], map [501] [501]; int BFS () {MEM (D,-1); queue <int> q; q. push (0); D [0] = 0; while (! Q. empty () // find the augmented path {int u = Q. front (); q. pop (); For (int v = 0; v <= N; V ++) {If (d [v] =-1 & map [u] [v]) {d [v] = d [u] + 1; // layered, the larger the number of layers, the more Q. push (v) ;}} return d [N]! =-1;} int DFS (int u, int min) {int sum; If (u = N) return min; For (int v = 0; v <= N; V ++) if (Map [u] [v] & D [v] = d [u] + 1 & (sum = DFS (v, min (Min, map [u] [v]) {map [u] [v]-= sum; Map [v] [u] + = sum; return sum ;} return 0;} int dinic () {int TMP, ANS = 0; while (BFS () {While (TMP = DFS (0, INF) ans + = TMP ;} return ans;} int main () {// freopen ("1.txt"," r ", stdin); int N, F, D, FF, DD, I, j, mm; scanf ("% d", & N, & F, & D); for (I = 1; I <= N; I ++) {scanf ("% d", & ff, & DD); For (j = 0; j <ff; j ++) {scanf ("% d ", & mm); map [mm + N * 2] [I] = 1 ;}for (j = 0; j <dd; j ++) {scanf ("% d", & mm); map [I + N] [mm + N * 2 + F] = 1 ;} map [I] [I + N] = 1; // the cows are connected to each other, saving that each ox matches only one group of food and drinks} for (I = N * 2 + 1; I <= N * 2 + F; I ++) map [0] [I] = 1; // Connection source point N = N * 2 + F + D + 1; for (I = N * 2 + F + 1; I <= N * 2 + F + D; I ++) map [I] [N] = 1; // connection point printf ("% d \ n", dinic (); Return 0 ;}
Single-path augmented code of dinic:
# Pragma comment (linker, "/Stack: 1024000000,1024000000 ") # include <iostream> # include <cstdio> # include <cstring> # include <algorithm> # include <map> # include <queue> # include <set> # include <cmath> # include <bitset> # define MEM (, b) memset (a, B, sizeof (A) # define lson I <1, L, mid # define rson I <1 | 1, Mid + 1, R # define llson j <1, L, mid # define rrson j <1 | 1, Mid + 1, R # define INF 0x7ffffffftypedef long ll; typedef unsigned long Long ull; using namespace STD; # define maxn 2000005int N, CNT, d [maxn], head [maxn], go [maxn], Q [maxn]; struct node {int V, W, next;} e [maxn]; void add (int u, int V, int W) {e [CNT]. V = V; E [CNT]. W = W; go [CNT] = CNT + 1; E [CNT]. next = head [u]; head [u] = CNT ++; E [CNT]. V = u; E [CNT]. W = 0; go [CNT] = cnt-1; // At the beginning, the reverse edge weight is written as W, always wa E [CNT]. next = head [v]; head [v] = CNT ++;} int BFS () {MEM (D,-1); int L = 0, r = 0; Q [R ++] = 0; d [0] = 0; while (L <r) // find the augmented path {Int u = Q [L ++]; for (INT v = head [u]; V! =-1; V = E [v]. next) {If (d [E [v]. v] =-1 & E [v]. w) {d [E [v]. v] = d [u] + 1; // layered, the more backward, the larger the number of layers if (E [v]. v! = N + 1) Q [R ++] = E [v]. V ;}} return d [N]! =-1;} int DFS (int u, int min) {int sum; If (u = N) return min; For (INT v = head [u]; V! =-1; V = E [v]. Next) // Min-duolu! If (E [v]. W & D [E [v]. v] = d [u] + 1 & (sum = DFS (E [v]. v, min (Min, E [v]. w) {e [v]. w-= sum; E [go [v]. W + = sum; return sum;} return 0;} void Init () {MEM (Head,-1), Mem (go, 0), CNT = 0 ;} int dinic () {int TMP, ANS = 0; while (BFS () {While (TMP = DFS (0, INF) ans + = TMP;} return ans ;} int main () {// freopen ("1.txt"," r ", stdin); int N, F, D, FF, DD, I, j, mm; scanf ("% d", & N, & F, & D); Init (); for (I = 1; I <= N; I ++) {scanf ("% d", & ff, & DD); For (j = 0; j <ff; j ++) {scanf ("% d ", & mm); add (mm + N * 2, I, 1) ;}for (j = 0; j <dd; j ++) {scanf ("% d ", & mm); add (I + N, mm + N * 2 + F, 1);} Add (I, I + N, 1); // self-connection between cattle, save each ox to match only one group of food and drinks} for (I = N * 2 + 1; I <= N * 2 + F; I ++) add (0, I, 1); // source point N = N * 2 + F + D + 1; for (I = N * 2 + F + 1; I <= N * 2 + F + D; I ++) add (I, n, 1); // connection point printf ("% d \ n ", dinic (); Return 0 ;}
Multi-path augmented code of dinic:
# Pragma comment (linker, "/Stack: 1024000000,1024000000 ") # include <iostream> # include <cstdio> # include <cstring> # include <algorithm> # include <map> # include <queue> # include <set> # include <cmath> # include <bitset> # define MEM (, b) memset (a, B, sizeof (A) # define lson I <1, L, mid # define rson I <1 | 1, Mid + 1, R # define llson j <1, L, mid # define rrson j <1 | 1, Mid + 1, R # define INF 0x7ffffffftypedef long ll; typedef unsigned long Long ull; using namespace STD; # define maxn 2000005int N, CNT, d [maxn], head [maxn], go [maxn], Q [maxn]; struct node {int V, W, next;} e [maxn]; void add (int u, int V, int W) {e [CNT]. V = V; E [CNT]. W = W; go [CNT] = CNT + 1; E [CNT]. next = head [u]; head [u] = CNT ++; E [CNT]. V = u; E [CNT]. W = 0; go [CNT] = cnt-1; // At the beginning, the reverse edge weight is written as W, always wa E [CNT]. next = head [v]; head [v] = CNT ++;} int BFS () {MEM (D,-1); int L = 0, r = 0; Q [R ++] = 0; d [0] = 0; while (L <r) // find the augmented path {Int u = Q [L ++]; for (INT v = head [u]; V! =-1; V = E [v]. next) {If (d [E [v]. v] =-1 & E [v]. w) {d [E [v]. v] = d [u] + 1; // layered, the more backward, the larger the number of layers if (E [v]. v! = N + 1) Q [R ++] = E [v]. V ;}} return d [N]! =-1;} int DFS (int u, int min) {int sum, duolu = 0; If (u = N) return min; for (INT v = head [u]; V! =-1 & Min-duolu> 0; V = E [v]. Next) // Min-duolu this multi-channel augmented approach is really amazing! If (E [v]. W & D [E [v]. v] = d [u] + 1 & (sum = DFS (E [v]. v, min (min-duolu, E [v]. w) {e [v]. w-= sum; E [go [v]. W + = sum; duolu + = sum;} return duolu;} void Init () {MEM (Head,-1), Mem (go, 0), CNT = 0 ;} int dinic () {int TMP, ANS = 0; while (BFS () {While (TMP = DFS (0, INF) ans + = TMP;} return ans ;} int main () {// freopen ("1.txt"," r ", stdin); int N, F, D, FF, DD, I, j, mm; scanf ("% d", & N, & F, & D); Init (); for (I = 1; I <= N; I ++) {scanf ("% d", & ff, & DD); For (j = 0; j <ff; j ++) {scanf ("% d ", & mm); add (mm + N * 2, I, 1) ;}for (j = 0; j <dd; j ++) {scanf ("% d ", & mm); add (I + N, mm + N * 2 + F, 1);} Add (I, I + N, 1); // self-connection between cattle, save each ox to match only one group of food and drinks} for (I = N * 2 + 1; I <= N * 2 + F; I ++) add (0, I, 1); // source point N = N * 2 + F + D + 1; for (I = N * 2 + F + 1; I <= N * 2 + F + D; I ++) add (I, n, 1); // connection point printf ("% d \ n ", dinic (); Return 0 ;}
Poj 3281 network stream (dinic adjacent matrix, single-channel augmented, multi-channel augmented)