ネイチャー二部グラフ
定理:回数は、各ループグラフGが偶数である場合にのみ、Gは、二部グラフであればありません。何ループが存在しない場合、ループ数が0のいずれかに相当し、それはまた、二部グラフとして考えられます。
二部グラフの決定
グラフが接続されている場合、次のような方法は、二部グラフであるか否かを判断することができる。
図中の頂点v必要に応じて、定義された距離は0の番号が付けられ、次に隣接する基準点を配置している距離は、次に、1でありますように示され、そして、全ての基準点は、基準2(基準点がない場合)に隣接しています。
ラベリング処理は、BFSを達成するために使用することができます。参照した後、Xユニットとして分類されたすべての奇数点は、基準もポイントY部分として分類されます。
次に、それは二部グラフを順次二つのエンドポイントかどうかを確認するために、それぞれの側をチェックして判断される部分における部分X、Yです。
グラフが接続されていない場合は、通信中の各ブロックのために決定されます。
パスの拡張。
あなたは慎重に読み、マップを描いている場合は難しい場合は、増強パスを見つけるために見つけ、その後、ペアの数が1つ増えています。だから、実際には、パスを増大させるの本質は、ペアなしの始点と終点のパス側です。
ハンガリーのアルゴリズム:
これは、ハンガリーのアルゴリズム(ハンガリー法)1965年ハンガリーの数学エドモンズによって提案されたもの、いわゆるハンガリーアルゴリズムと呼ばれています。ハンガリー二部グラフ・マッチングアルゴリズムは、最も一般的なアルゴリズムで、アルゴリズムの核心は、パスアルゴリズムを増大させると二部グラフの最大マッチング要求で増強経路を見つけることです。
複雑さ:
時間計算量:O(N3)の最悪の隣接行列
O(MN):隣接テーブル
複雑スペース:隣接行列:O(N 2)
隣接テーブル:O(N + M)
もう一つの重要な概念:二部グラフ
2部グラフグラフ理論は、特別なモデルです。頂点Vは、関連する2つの互いに素図各エッジ(i、j)の中に(A、B)2つのサブセットに分割することができる場合にG =(V、E)を設定すると、無向グラフです。頂点iとjは頂点の2つの異なるセットに属し、二部グラフ図のGと呼ばれます。
手短に言えば、Vは頂点の集合は、2つの互いに素な部分集合に分割することができ、各図面の2つの頂点は、2つの互いに素な部分集合、2つのサブセットに属する縁部に取り付けられています頂点は隣接していません。そのような満足は、図中二部グラフと呼ばれます。
しかし、どのように我々は、グラフは二部グラフでない判断していますか???
実際には、それは、ライン上に赤と青のドットを使用する方法は難しいことではありません。全てのこのようにして、着色染料、及び隣接する頂点の色のすべての頂点が、その後、数字である場合、最初に染色赤色に言えば、任意の頂点は、次に青色に染色点に隣接する頂点は、異なっていてもよいです二部グラフ。
1つ の#define MAXV 1000年// この主題は、カスタムに基づくべきである 2 3。ベクトル< INT > G [MAXV]; // 図 4。 INT V; // 頂点の数 5。 INTカラー【MAXV]; // 頂点色(1又は-1) 。6 。7 // 頂点v、色C 8。 BOOL DFS(int型 V、INT C){ 9。 色[V] = C; 10 // 隣接する頂点の頂点上の電流スイープ 。11 用(INT I = 0 ;私はG [V] .sizeを< (); I ++){ 12 // 隣接頂点の色で染色されている場合、記載されていない二部グラフ 13である IF(カラー[G [V] [I]] == C)復帰 はfalse ; 14 // そうでない場合には染色された隣接する頂点、染色-c、要件は隣接する頂点を参照満たし 15を IF(カラー[G [V] [I]] == 0 && DFS(G [V] [I]、 - C)!)リターン falseに、 16 } 17 // 現在の頂点にアクセスするには問題の説明が頂点部グラフ形成しなくてもよい場合は 18である 返す trueに; 19 } 20は、 21である ボイド(解決){ 22は //の図を伝達しないことができるので、各頂点ごとのDFS 23はある ために(int型 I =0 ;私はVを<; I ++は){ 24 IF(色[I] == 0 ){ 25 // 。第1のカラーポイント 26は IF!(DFS(I、1 )){ 27 COUT << " いいえ" << ENDL; 28 リターン; 29 } 30 } 31である } 32 }
ハンガリーのアルゴリズム
パスを増強する役割があるので、我々は一致するスキームを発見した場合は、上記の説明によると、困難な場合は、現在のマッチングプログラムで見つけるために見つけるもはや、そして、(すなわち、一致の数を増やす)「マッチング制度を改善しないように」任意増強パスは、現在の一致は、次のようなアルゴリズムであり、最大のマッチ二部グラフです。
まず、任意の点からUはUは側縁から選択される任意の点から不対開始ペアリングを開始する(V>エッジがU-からのものであると仮定して)。点v対になっていない場合は、ペアリングが成功すると、それは彼らが増強パスを見つけています。Vポイントは既にこの時点での試みが成功した場合、それはオリジナルのペアリング関係を更新し、ペアリング、および「連鎖反応」にしようとして行ってきましたされている場合。
そこでここでは、[V] = uの一致を使用します。ペアリングは、それがペアプラス1されます成功しています。
側の選択されたペアがちょうど失敗した場合2.は、再度試してみ片側の再選の端からUを指します。ポイントuのペアリングが成功するまで、またはuのすべてのエッジをアップ指すようにしようとしました。
3.すべての点が、完了しようとしている新しい増強パスまで見つけることができないまで、次に、ポイントの残りの不対のペアを1つずつを継続します。
出力ペアの4数。
1 / * 2 1)、その後、前の紛争、以前の優先収率の場合 3 2)前回の譲歩後のCPで利用可能でない場合は、以前には、一致を見に行くために新しい監督を譲歩を拒否しました。 4 3)新たなマッチが誰それに、次に、1つのバーではない場合 5。 * / 6の#include <ビット/ STDC ++ H.> 7。 の#define MAXN 1000100 8。 使用した 名前空間STD; 9のtypedef 構造体{ 10 INT から、次に、に; 11 int型の重量; 12である } EDGE、 13である EDGEエッジ[MAXN]; 14 int型のヘッド[MAXN]、CNT = 1 ; // 最初のアクセスポイントで始まり 15 INT一致[MAXN]、[MAXN] DFN。// 匹配数组、时间戳数组 16 空隙追加(INT から、INT に) 17 { 18 のエッジ[CNT]。= から。 19の エッジ[CNT] .TO = であり; 20の [エッジ[CNT] .next =先頭から]。 21 [先頭から ++ = CNT] 。 22 } 23 BOOL DFS(INT U、int型VIST) 24 { 25 のための(int型 I =ヘッド[U]; I; I = エッジ[I] .next) 26である { 27 IF(DFN [エッジ[I] .TO] =!ビスト) 28 { // アクセスがラウンドされていない場合 29 DFN [エッジ[I]は.TO] =ビスト; // タグ訪問 30を IF(!一致[エッジ[I] .TO] || DFS(一致[エッジ[I] .TO]、ビスト)) 31である { // 増強パスが一致から出発した場合に 32 エッジ[マッチI] .TO] = U; 返す trueに、 33である } 34れる } 35 } 36 リターン falseに; 37 } 38れます 39 のint main()の 40 { 41 INT N、M、E、CIN >> N >> M >> E。 42 INT ANS = 0 。 43 のために(int型 I = 0 ; iがEを<Iは++ ) 44 { 45 INT A、B、CIN >> A >> B。 46 であれば(> N || B> M)続けます。 47 追加(A、B)。 48 } 49 のための(int型 I = 1は iが++; iがn = < ) 50 { 51 もし(DFS(私は、私は))++ ANS ; 52 } 53 COUT << ANS << ENDL。 54 リターン 0 ; 55 }