シンプルな2部グラフマッチング問題。
GO:羅区
前風水。
エッジの内側に見ているからスキームをペアリング:
- これは、右側の値は0でなければなりません
- 特定のソースの間に1〜M、M + 1との間のシンク定数〜N
- ダイレクト出力が可能。
1つの#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3 のconst int型 N = 1100 。 4 のconst int型 INF = 1E9。 5 int型 M、N、S、T、CNT = - 1 、maxflow。 6 INTの D [N]、ヘッド[N << 1 ]。 7 構造体の縁{ INT次に、F、から ;} E [N << 1 ]。 8 ボイド addedge(INT から、INTに、int型の F){E [++ CNT] =(エッジ){ヘッドへ〔から]、F、より };ヘッド【から】= CNT;} 9つのインラインブールBFS(){ 10 のmemset(D、0、はsizeof (d)参照)。 11 キュー< 整数 > Q; 12 q.push(S)。 13 D [S] = 1 。 14 一方(q.size()){ 15 INT U = q.front()。 16 q.pop()。 17 のために(int型 - ;!私=私は=頭部[U] 1 ; I = {E [I] .next) 18 のint V = E [i]を.TO、= fはE [i]は.F。 19 もし(D [V] || F!)続けます。 20 D [V] = D [U] + 1 。 21 q.push(V)。 22 であれば(V == T)リターン 1 。 23 } 24 } 25 リターン 0 。 26 } 27 28 int型 dinic(INT U、INT フロー){ 29 であれば(U == T)戻り流; 30 int型の残り= 流れ。 31 のための(int型I =ヘッド[U];!I = - 1 &&休息; I = E [I] .next){ 32 のint V = E [i]の.TO、F = E [I] .F。 33 であれば(F || D [V] = D [U] +!1)続けます。 34 int型 K = dinic(V、分(残り、f)参照)。 35 もし D [V] =(K!)0 。 36 他{ 37 E [i]の.f- = K。 38 E [I ^ 1 ] .F + = K。 39 REST- = K。 40 } 41 } 42 リターン flow-残り; 43 } 44 ボイド(解決){ 45 INTは今= 0 。 46 一方(BFS()){ 47 ながら(今= dinic(S、INF)) 48 maxflow + = 今。 49 } 50 であれば(!maxflow){ 51 のprintf(" いいえ解決!" )。 52 } 53 他{ 54 のprintf(" %d個の\ n " 、maxflow)。 55 のための(int型i = 0 ; iが<= CNTを、私は++ ){ 56 であれば(E [I] .F && E [I]!から > 0 && E [I] から <= M && E [I] .TO> M && E [I] .TO <= N){ 57 のprintf(" %D%D \ n "、E [I] からE [I] .TO)。 58 } 59 } 60 } 61 } 62 INT メイン(){ 63 のmemset(ヘッド、 - 1、はsizeof (ヘッド))。 64 のscanf(" %D%dの"、&M、&65 INT X = 0、Y = 0 。 66個の S = 0、T = N + 1 。 67 一方、(1 ){ 68 のscanf(" %D%dの"、およびX&Y)。 69 であれば(X < 0)ブレーク。 70 addedge(X、Y、1 )。 71 addedge(Y、X、0 ); 72 } 73 のための(int型 I = 1 ; I <= M; iは++ ){ 74 addedge(S、I、1 )。 75 addedge(I、S、0 ); 76 } 77 のための(int型 iがm + = 1 ; iが<= N; iが++ ){ 78 addedge(I、T、1 ); 79 addedge(T、I、0 ); 80 } 81 )(解きます。 82 リターン 0 ; 83 }
ポイントZhenshuang!