Title: http: //uoj.ac/problem/79
Nothing to say, just different from the bipartite graph
Algorithms: algorithms with trees and flowers
#include<bits/stdc++.h> using namespace std; #define fo(i,a,b) for(int i=a;i<=b;i++) #define fod(i,a,b) for(int i=b;i>=a;i--) const int N=550; int n,head[N],pre[N],match[N],f[N],col[N],cmp[N],tot; const int M=5e5+5; struct node{ int u,v,nextt; }e[M]; int num; void addedge(int u,int v){ e[num].v=v; e[num].nextt=head[u]; head[u]++ NUM = ; } int Find ( int X) { return F [X] X X ==:? F [X] = Find (F [X]); } int lca ( int X, int Y) { // entire lca achieve more clever, because it is BFS, then the two points on the current depth must equal the odd ring, alternately looking lca violence can be. TOT ++ ; X = Find (X), Y = Find (Y); the while (! CMP [X] = TOT) { CMP [X] = TOT; X = Find (pre [match [X]]); IF (Y ) the swap (X, Y); } return X; } Queue <int > que; void the make ( int X, int Y, int W) { // condensed ring (flowering) during the while (! Find (X) = W) { pre [X] = Y, Y = match [X]; // the X-is the original black spots, y is the original white point, the original pre turns into a double edge. IF (COL [y] == 2 ) // if y is dyed black or white point COL [y] = . 1 , que.push (y); IF (Find (X) == X) F [X] = W ; IF (Find (Y) == Y) F [Y] = W; X = pre [Y]; } } int solve(int st){ while(!que.empty()) que.pop(); que.push(st); fo(i,1,n) f[i]=i,pre[i]=col[i]=0; col[st]=1;//1 is black while(!que.empty()){ int u=que.front(); que.pop(); for(int i=head[u];~i;i=e[i].nextt){ int v=e[i].v; if(Find (V) == Find (U) || COL [V] == 2 ) Continue ; // If one had already reduced or even odd cycloalkyl ring is skipped IF (! {COL [V]) COL [V] = 2 , pre [V] = U; IF {(match [V]!) // find augmenting path for ( int X = V, y; X; X = y) { // return the modified matching y = match [pre [X]]; match [X] = pre [X]; match [pre [X]] = X; } return . 1 ; } // otherwise it is added to the queue matching point COL [match [V]] = . 1 ; que.push (match [V]); } the else { int the LCA = LCA (U, V); the make (U, V, the LCA); the make (V, U, the lCA); // above were modified to lca path and the path to v lca (the two halves) loop } } } return 0 ; } int main () { int m; Memset (head, - . 1 , the sizeof (head) ); Scanf ( " % D% D " , & n-, & m); FO (I, . 1,m){ int u,v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } int ans=0; fo(i,1,n) if(!match[i]) ans+=solve(i); printf("%d\n",ans); fo(i,1,n) printf("%d ",match[i]); return 0; }