[最大フロー、dinic] P2055 [ZJOI2009]休日のホステル

  1の#include <iostreamの>
   2の#include <キュー>
   3の#include <CStringの>
   4  使用して 名前空間をSTD。
  5  
  6  CONST  INT MAXN = 60   7  
  8  CONST  INT INF = 0x3f3f3f3f   9  INT N。
10  int型のヘッド[MAXN << 2 | 1 ]。
11  int型CNT。
12  INT D [MAXN << 2 | 1 ]。
13  int型になりました[MAXN <<2 | 1 ]。
14  INT 学校[MAXN]。
15  INT ホーム[MAXN]。
16  INT ST、エド。
17  
18  構造体のエッジ
 19  {
 20      int型V、NXT、W。
21 } E [MAXN << 4 | 1 ]。
22  
23  空隙 add_dinic(INT U、INT V)
 24  {
 25      E [++ CNT] .V = V。
26      E [CNT] .W = 0 27      E [CNT] .nxt =ヘッド[U]。
28      頭[U] = CNT。
29  }
 30  
31インラインボイド追加(INT U、INT V、INT w)の
 32  {
 33      E [++ CNT] .V = V。
34      E [CNT] .W = W。
35      E [CNT] .nxt = 頭部[U]。
36      頭[U] = CNT。
37      add_dinic(V、U)。
38  }
 39  
40  INT dfs_dinic(int型のx、int型フロー)
 41  {
 42     もし(X ==編)リターン・フロー;
43の     INTは RES = 0 44      のためにINT - ;!I = I [x]は今= 1 ; iが= E [I] .nxt)
 45      {
 46          のint V = E [I] .Vと、
47          であれば(D [V] + 1 == D [X] && E [I] .W> 0 48          {
 49              のint、K = dfs_dinic(V、分(E [I] .W、流量))。
50の              RES + = K。
51              流れ- = K。
52             E [i]は.W - = K。
53              E [I ^ 1 ] .W + = K。
54              もし(!フロー)ブレーク55          }
 56      }
 57の     リターンRES。
58  }
 59  
60  ブールbfs_dinic()
 61  {
 62      のmemset(D、0はsizeof (d)参照)。
63      キュー< 整数 > Q;
64      q.push(ED)。
65      D [ED] = 1 66      しばらく(!q.empty())
 67      {
 68          int型のu = q.front();
69          q.pop()。
70          のためにINTは iはヘッド[U] =; I =! - 1 ; iが= E [I] .nxt)
 71          {
 72              のint V = E [I] .Vと、
73              であれば(D [V] && E [I ^!1 ] .W> 0 74              {
 75                  q.push(V)。
76                  D [V] = D [U] + 1 77              }
 78          }
79      }
 80      リターン D [ST]> 0 81  }
 82  
83  
84  int型dinic() 
 85  {
 86      のintフロー= 0 87      一方(bfs_dinic()) 
 88      {
 89          のためにINTは iは= 0 ; I <= ED; I ++)は[I] = 頭部[I]。
90          フロー+ = dfs_dinic(ST、INF)。
91      }
 92      リターン流;
93  }
 94  
95  INTmain()の
 96  {
 97      INT T。
98      CIN >> T。
99      一方(T-- 100      {
 101          のmemset(ヘッド、 - 1はsizeof (ヘッド))。
102          CNT = 1 103          // 源点0、汇点2N + 1つの
104          CIN >> N。
105          INT TOT = 0 106          ST = 0 107          編= N << 1 | 1 ;
108         以下のためにINT iが= 1 ; I <= N; I ++ 109          {
 110              CIN >> 学校[I]。
111              であれば(学校[I])を追加する(I + N、ED、1 )。
112          }
 113          INT iは= 1 ; iが<= N; I ++ 114          {
 115                  CIN >> ホーム[I]。
116                  もし(!(ホーム[I] &&学校[i])と||学校[i]が!)を追加(ST、I、1)、TOT ++ ;
117          }
 118          int型私は= 1 ; I <= N。I ++ 119          {
 120              のためのINT J = 1 ; J <= N; J ++ 121              {
 122                  INTのT。
123                  cinを>> トン。
124                  もし(T || I == j)の追加(I、J + N、1 )。
125              }
 126          }
 127          INT ANS = 0 128          ANS = dinic()。
129          の場合(ANS> = TOT)はcout << " ^ _ ^" << ENDL;
 130          そう COUT << " T_Tは、 << ENDL;
 131          のmemset(今、0はsizeof (現在));
 132      }
 133 }
コードの表示

 

おすすめ

転載: www.cnblogs.com/thjkhdf12/p/11823724.html