木々や花のアルゴリズム:一般的なグラフの最大マッチング

グラフのG V E その試合、Mは、タプルU V 前記、そのセットU V V、(U、V)∈E、及び重複ポイントMは存在しません。

| M |の最大の時間、私たちは呼んでMをするGの最大マッチング。

場合Gは、その最大のマッチングが古典的なハンガリーのアルゴリズムまたはネットワーク・フロー・アルゴリズムを用いて解くことができる二部グラフです。しかし、Gは直接増強し、一般的なビューが可能になるであり、この時、私たちは、一致するタスクを完了するために木や花でアルゴリズムを使用しています。

1の#include <cstdioを>
 2の#include <CCTYPE>
 3の#include <CStringの>
 4の#include <アルゴリズム>
 5  使用して 名前空間をSTD。
6  INTのリード(){
 7      INT X = 0、F = 1 8      チャー C = GETCHAR()。
9      (!C = GETCHAR(); isdigit(c)参照)場合(C == ' - ' F =) - 1 10      のために(; isdigit(C); C = GETCHAR())X = X * 10 + C- ' 0 ' 11      リターン X * F。
12  }
 13  のconst  int型 MAXN = 505 14  CONST  INT MAXM = MAXN * MAXN * 2 15  整数 N、M、QUE [MAXM]、QL、QR、予め[MAXN]、ティム= 0 16  構造体端{
 17      int型V、NXT。
18  } E [MAXM]。
19  INT H [MAXN]、TOT = 0 20  INT 一致[MAXN]、F [MAXN]、TP [MAXN]、チック[MAXN]。
21  INT検索(INT X){
 22      リターンF [X] == X F [X]:F [X] = 検索(F [X])。
23  }
 24  空隙追加(INT U、INT V){
 25      E [++ TOT = (エッジ){V、H [U]}。
26      H [U] = TOT。
27  }
 28  int型 LCA(int型のx、int型のY){
 29      のために(++ティム;;スワップ(X、Y))場合(x)は{
 30          、X = (X)を見つけます。
31          であれば(TIC [X] == TIM)リターン X。チック[X] =ティム、X = プレ[マッチ[X]]。
32      }
 33 }
 34  ボイド収縮(int型のx、int型の Y、int型P){
 35      ながら、((X)=を見つける!{P)
 36          プレ[X] = Y、Y = 一致[X]を、
37          であれば(TP [Y] == 2)[Y] = TP 1、QUE [++ QR] = Y。
38          もし F [X] =((X)== X見つける。)Pは、
39          であれば(検索(Y)== Y)[Y] F = P。
40          X = プレ[Y]。
41      }
 42  }
 43  ブール 8月(INT S){
 44      INTは iは= 1 ; I <= N; ++ I)F [I] = I。
45      のmemset(TP、0はsizeof TP)、memsetの(前、0はsizeof PRE)。
46      TP [QUE [QL = QR = 1 ] = S] = 1// 1:タイプA; 2:B型
47      INT T = 0 48      一方(QL <= QR){
 49          、INT X = QUE [QL ++ ]。
50          のためにintは私は、電子を= [I] .nxt、V =; I iは、[X]、V = E [I] .V時間= {E [I] .V)
 51              もし([V] == ||)(TPのxを求める==(V)を見つける2続けます52              であれば(!TP [V]){
 53                  TP [V] = 2 [V] =予備X。
54                  であれば(!{一致[V])
 55                      のためのintは今= V、最後に、TMP、今、今= 最後){
 56                          最後=一致[TMP = プレ[今]。
57                          試合[今] = tmpに、一致[TMP] = 今。
58                      }
 59                      リターン 60                  } 
 61                 TP [マッチ[V] = 1、QUE [++ QR] = 一致[V]。
62              } そう であれば(TP [V] == 1 ){
 63                  のint L = LCA(X、V)。
64                  収縮(X、V、L)。
65                  収縮(V、X、L)。
66              }
 67          }
 68      }   
 69      リターン はfalse ;
70  }
 71  、INT (){主
 72  ONLINE_JUDGE #ifndefの
 73      freopenは(" test.in ""R "STDIN);
 74      freopenは(" my.out " " W 、STDOUT);
 75 #endifの76      N =(読み取り)、M = read()は、
 77 のためにINTは私= 1、I <= M。 ; ++ I){
 78 、INT X =(読み取り)、Y = (読み取り);
 79         追加(x、y)は、(Y、X)を加える;
 80     }
 81 INT ANS = 0 ;
 82 INT I = 1 ; I <= N; ++ I)ANS + =(一致[I] &&!8月(I))。
 
                          83      のprintf(" %dの\ n " 、ANS)。
84      のためにINT iは= 1 ; iが<= N; ++ I)のprintf(" %dの" 、マッチ[I])。
85の      プット("" )。
86      リターン 0 ;
87 }

元のタイトルはUOJ79で、ANSはいi番目の個人の配偶者を表しマッチの最大数、試合[i]があります。

 

おすすめ

転載: www.cnblogs.com/St-Lovaer/p/11945534.html