Luo Gu P3386 bipartite graph matching

Original title link

 

Nature bipartite graph


Theorem: no if and only if the number of times each loop graph G are an even number, G is a bipartite graph. If there is no loop, the loop number is equivalent to any one of 0, it is also considered as a bipartite graph.

Determining a bipartite graph


If a graph is connected, the following method can be determined whether a bipartite graph is:
optionally a vertex v in the figure, a distance defined numbered 0, then the distance that are located adjacent reference points is 1, then the All reference points are adjacent to a reference 2 (if the reference point is not the case), as shown, and so on.
The labeling process can be used to achieve a BFS. After the reference, all odd numbered points classified as X unit, reference is even classified as a point Y portion.
Next, it is determined bipartite graph is sequentially checking each side, to see if the two end points is a portion X, a Y in the portion.
If a graph is not connected, it is determined for each block in the communication.

Augmenting paths.

If you read carefully and painted map, find if difficult to find an augmenting path, then the number of pairs is increased by one. So, in fact, the essence of augmenting path is a path side of the start and end points of the paired none.


Hungarian algorithm:

This is called Hungarian algorithm (Hungarian method) what is proposed by the Hungarian mathematician Edmonds in 1965, so called Hungarian algorithm. Hungary bipartite graph matching algorithm is the most common algorithm, the core of the algorithm is to find augmenting path, which is a bipartite graph maximum matching demand with augmenting path algorithm.

the complexity:

Time complexity: the adjacency matrix of the worst of O (n3)
adjacency table: O (mn)
Complexity Space: the adjacency matrix: O (n2)
adjacency table: O (n + m)

Another important concept: the bipartite graph

Bipartite graph graph theory is a special model. Setting G = (V, E) is an undirected graph, if the vertex V may be divided two subsets (A, B) into two disjoint and FIG each edge (i, j) associated vertices i and j belong to the two different sets of vertices, called a bipartite graph G of FIG.

Briefly, V is the set of vertices may be partitioned into two disjoint subsets, and two vertices of each drawing are attached to edges belonging to two disjoint subsets, the two subsets vertices are not adjacent. Such satisfy called bipartite graph in FIG.

But how do we judge a graph is not bipartite graph? ? ?

In fact, it is not difficult, the method used red and blue dots on the line. First, an arbitrary vertex speaking dyed red, then the point adjacent vertices stained blue, may be different if all vertices of all the colored dye in this manner, and the color of the adjacent vertex, then the figure is a bipartite graph.

. 1  #define MAXV 1000 // this subject should be based on a custom 
2  
. 3 Vector < int > G [MAXV];   // FIG 
. 4  int V;                        // number of vertices 
. 5  int Color [MAXV];   // vertex colors (1 or -1) 
 . 6  
. 7  // vertex v, color C 
. 8  BOOL DFS ( int v, int C) {
 . 9      color [V] = C;
 10      // the current sweep over adjacent vertices vertices 
. 11      for ( int I = 0 ; i <G [v] .size (); i ++) {
 12          // if the neighboring vertex has been dyed with the color, not described bipartite graph 
13 is          IF (Color [G [V] [I]] == C) return  to false ;
 14          // If not stained adjacent vertices , dyed -c, meets the requirements see adjacent vertices 
15          iF (Color [G [V] [I]] == 0 && DFS (G [V] [I], - C)!) return  to false ;
 16      }
 17      // If no problem description to access the current vertex may be formed bipartite graph vertex 
18 is      return  to true ;
 . 19  }
 20 is  
21 is  void Solve () {
 22 is      // may not communicate FIG, so each vertex once every dfs 
23 is      for ( int I =0 ; I <V; I ++ ) {
 24          IF (Color [I] == 0 ) {
 25              // first color point. 1 
26 is              IF ! (DFS (I, . 1 )) {
 27                  COUT << " No " << endl;
 28                  return ;
 29              }
 30          }
 31 is      }
 32 }
View Code

Hungarian algorithm

According to the above description, since the role of augmenting path is "to improve the matching scheme" (ie, increase the number of matched), then if we have found a matching scheme, no longer find if difficult to find in the current matching program any augmenting path, then the current match is the biggest match bipartite graph, the algorithm is as follows.

1. First, from an arbitrary point u unpaired start from any point u is selected from a side edge (assuming that the edge is from u-> v) to start pairing. If the point v unpaired, the pairing is successful, it is they found an augmenting path. V If the point has already been paired, and went to try to "chain reaction", if this time the attempt is successful, it updates the original pairing relationship.
So here we use a matched [v] = u. The pairing is successful it will be paired plus one ,.

2. If the selected pair of side just failed, it would point u from the edge of the re-election of one side to try again. Until the point u pairing is successful, or tried to point up all the edges of u.

3. Next to continue through the remaining unpaired pair of points one by one, until all the points have been trying to complete, can not be found until the new augmenting paths.

4. Number of output pair.

1  / * 
2  1) If the subsequent and previous conflict, the previous priority yield
 3  2) If not available at cp after previous concessions, the previous rejected concessions, the new superintendent to go look for a match.
. 4  3) If the new match is not who on it, then, the single bar
 . 5  * / 
. 6 #include <bits / STDC ++ H.>
 . 7  #define MAXN 1000100
 . 8  the using  namespace STD;
 . 9 typedef struct {
 10      int  from , to, Next;
 . 11      int weight;
 12 is  } EDGE;
 13 is  EDGE Edges [MAXN];
 14  int head [MAXN], CNT = . 1 ; // start with the first access point 
15  int match[MAXN],dfn[MAXN];//匹配数组,时间戳数组
16 void add(int from ,int to)
17 {
18     edges[cnt].from=from;
19     edges[cnt].to=to;
20     edges[cnt].next=head[from];
21     head[from]=cnt++;
22 }
23 bool dfs(int u,int vist)
24 {
25     for(int i=head[u];i;i=Edges [I] .next)
 26 is      {
 27          IF ! (DFN [Edges [I] .to] = Vist)
 28          { // If access is not round 
29              DFN [Edges [I] .to] = Vist; // tag visited 
30              IF (! match [Edges [I] .to] || DFS (match [Edges [I] .to], Vist))
 31 is              { // if augmenting path starting from the match 
32                  match [Edges [ I] .to] = U; return  to true ;
 33 is              }
 34 is          }
 35      }
 36      return  to false ;
 37 [  }
 38 is 
39 int main()
40 {
41     int n,m,e;cin>>n>>m>>e;
42     int ans=0;
43     for(int i=0;i<e;i++)
44     {
45         int a,b;cin>>a>>b;
46         if(a>n||b>m)continue;
47         add(a,b);
48     }
49     for(int i=1;i<=n;i++)
50     {
51         if(dfs(i,i))ans++;
52     }
53     cout<<ans<<endl;
54     return 0;
55 }
View Code

 

  

Guess you like

Origin www.cnblogs.com/tldr/p/11605278.html