Can test the template problem in uoj#79
Like the title, simply introduce the flower tree algorithm to provide a good template
An introduction to Amway a very detailed blog
Because I am too vegetableschinese ... This blog does not tell us any proof of the correctness of the algorithm.
(May later be interested in translating the original thesis: Efficientalgorithmsforfindingmaximalmatchingingraphs, but it must be lazy now.) )
Maybe some contestants would like to Gou vegetableschinese me as lazy, binary graph matching will only use the Dinic practice, suggest learning to take a flower tree before looking at the Hungarian algorithm
Like the Hungarian algorithm, the core of the flower tree algorithm is similar to finding the augmented path every time.
Assuming that for the K point of the original image, some matches have been found, and the matches are saved first.
Select a point s that has not yet been matched, as a starting point for BFS, keep the BFS tree
Every time we traverse to a point, if it doesn't match, that's great. Because of this, we find an augmented path that can be augmented directly.
Otherwise, remember this point for u, and remember that its mate is V
to point u, mark as T node, for V, Mark as S node, and put V on team, continue BFS
(with the starting point S, it's clear that all the points in the queue are S-class nodes)
Well, that's probably how the BFs tree was drawn.
Where the red node is the starting point
Obviously, some time, from a certain point of departure, the path of a point is visited, where to do.
To classify this node into a discussion
1. This point is a T-node
Just like the side of the blue line in the diagram, it is obvious that a even ring is found at this time, ignoring
2. This point is the S node
or the Blue line in the picture, you find a ring with an odd length
But the situation is not simple ... Obviously, there's no way to find a solution to construct an augmented road
However, if there is any point on the ring, there is an unmatched point in the point where the connection is made.
Then obviously, you can construct an augmented path that goes backwards.
So, at this point, any point on the odd ring that has an edge connection mismatch is equivalent.
You can then shrink the odd ring to a new point, and then proceed to BFS until you find the augmented path (or prove it does not exist).
So far, the basic steps of solving general graph matching with Flower tree algorithm are almost clear.
Bfs-> contraction ring->bfs-> contraction ring->...-> contraction ring->bfs-> find augmented path
So when we find the augmented path, we're going to reverse the match along the way, and we need to start each of the rings (flowers with flowers) along the road ...
No desire to write at all. I do not know where the code to begin ...
This side provides a I think easier to achieve the board. (Anyway, this algorithm is based on the board.) )
First of all, for each choice of BFS starting point, 1~n for once on the line
Each time you determine whether the current point has been paired, if not, do BFS
For each of the T-class points that are traversed, the record Pre[i] is numbered for the S-class point that finds it
Every time we find s, we need a shrink ring.
For the indented ring, just find the S point on the ring as its representative point
If a flower is included in another flower, then the flower is no longer represented.
In fact, we don't really have to do this process of shrinking loops,
Just make proper modifications to the pre array in each flower.
Probably as shown in the picture:
This is a case where S finds S.
You just have to make a big effort to connect each of the pre edges of S.
Obviously, if a point finds a legitimate matching object (that is, an unmatched point)
We can easily modify the ring that needs to be modified by the pre side.
The specific operation may refer to the function in my Code
Link is a shrink loop function
Rebuild for the pre side that needs to be changed
Augment is the augmented function
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include < cstring> #include <vector> #include <queue> #include <set> #include <map> #include <stack
> #include <bitset> using namespace std;
const int N = 505;
int n,m,cnt,num[105][7],fa[n],pre[n],mark[n],mat[n],vis[n];
Queue <int> Q;
Vector <int> V[n];
inline int GETFA (int x) {return x = = Fa[x]? x:fa[x] = GETFA (fa[x));
inline int getint () {Char ch = getchar (); int ret = 0; while (Ch < ' 0 ' | |
' 9 ' < ch) ch = getchar ();
while (' 0 ' <= ch && ch <= ' 9 ') ret = RET * + CH-' 0 ', ch = getchar ();
return ret;
void Build () {n = getint (); m = Getint ();
while (m--) {int x = Getint (), y = Getint (); V[x].push_back (y);
V[y].push_back (x);
} inline void augment (int p) {while (P!=-1) {int tmp = mat[pre[p]]; mat[p] = pre[p]; MAT[PRE[P]] =P
p = tmp;
} inline void Rebuild (int x,int Y,int LCA) {while (GETFA (x)!= LCA) {pre[x] = y;
if (fa[x] = = x) fa[x] = LCA;
if (fa[mat[x]] = = Mat[x]) fa[mat[x] = LCA; if (mark[mat[x]] = = 1) {Q.push (mat[x]);
MARK[MAT[X]] = 0;} y = mat[x];
x = Pre[y];
} inline void Link (int x,int y) {++cnt; int p = GETFA (x);
for (;;)
{Vis[p] = cnt; p = mat[p]; if (p = = 1) break;
p = GETFA (pre[p]); int LCA;
p = GETFA (y);
for (;; p = GETFA (Pre[mat[p])) if (vis[p] = cnt) {LCA = P; break;} Rebuild (X,Y,LCA);
Rebuild (Y,X,LCA);
inline int BFS (int s) {for (int i = 1; I <= n; i++) fa[i] = i,mark[i] = pre[i] =-1; while (! Q.empty ()) Q.pop (); Mark[s] = 0;
Q.push (s); while (! Q.empty ()) {int k = Q.front ();
Q.pop ();
for (int i = 0; i < v[k].size (); i++) {int to = V[k][i];
if (GETFA (to) = = GETFA (k)) continue; if (mark[to] = =-1) {mark[to] = 1; pre[to] = k;
if (mat[to] = = 1) {augment (to), return 1; } Mark[mat[to]] = 0;
Q.push (Mat[to]);
else if (mark[to] = = 0) Link (to,k);
} return 0;
int main () {#ifdef DMC freopen ("DMC.txt", "R", stdin); #endif int Ans = 0;
Build ();
for (int i = 1; I <= n; i++) Mat[i] =-1;
for (int i = 1; I <= n; i++) if (mat[i] = = 1) Ans + = BFS (i);
cout << Ans << Endl; for (int i = 1; I <= n; i++) printf ("%d%c", mat[i] = = 1? 0:mat[i],i = n?
' \ n ': ');
return 0; }