匹配
1 //KM 邻接矩阵 2 const int INF = 0x3f3f3f3f; 3 4 int n, pay[305][305]; 5 int match[305];//y方点对应的x方点 6 int lx[305], ly[305];//标号 7 int slack[305];//记录标号改变量 8 bool visx[305], visy[305]; 9 10 bool Hungary( int s ){ 11 visx[s] = true; 12 13 for( int i = 1; i <= n; i++ ){ 14 if( visy[i] ) continue; 15 if( lx[s] + ly[i] == pay[s][i] ){ 16 visy[i] = true; 17 if( match[i] == -1 || Hungary( match[i] ) ){ 18 match[i] = s; 19 return true; 20 } 21 } 22 else slack[i] = min( slack[i], lx[s] + ly[i] - pay[s][i] ); 23 } 24 25 return false; 26 } 27 28 void KM(){ 29 memset( match, -1, sizeof( match ) ); 30 memset( lx, 0, sizeof( lx ) ); 31 memset( ly, 0, sizeof( ly ) ); 32 for( int i = 1; i <= n; i++ ) 33 for( int j = 1; j <= n; j++ ) 34 lx[i] = max( lx[i], pay[i][j] ); 35 36 for( int i = 1; i <= n; i++ ){ 37 memset( slack, INF, sizeof( slack ) ); 38 while( 1 ){ 39 memset( visx, false, sizeof( visx ) ); 40 memset( visy, false, sizeof( visy ) ); 41 42 if( Hungary( i ) ) break; 43 else{ 44 int temp = INF; 45 for( int i = 1; i <= n; i++ ) 46 if( !visy[i] ) 47 temp = min( temp, slack[i] ); 48 for( int i = 1; i <= n; i++ ){ 49 if( visx[i] ) 50 lx[i] -= temp; 51 if( visy[i] ) 52 ly[i] += temp; 53 else 54 slack[i] -= temp; 55 } 56 } 57 } 58 } 59 }
1 //前向星 + 匈牙利bfs 2 const int MAXN = 105; 3 const int MAXM = 10005; 4 //////////////////////////////////// 5 struct Match{ 6 int to, next; 7 }ptos[MAXM], stop[MAXM]; 8 int pcnt, ph[MAXN], scnt, sh[MAXN]; 9 10 int pmatch[MAXN], smatch[MAXN];//p和s匹配的对象 11 int flag[MAXN], pre[MAXN]; 12 13 inline void init(){ 14 memset( pmatch, -1, sizeof( pmatch ) ); 15 memset( smatch, -1, sizeof( smatch ) ); 16 memset( ph, -1, sizeof( ph ) ); 17 memset( sh, -1, sizeof( sh ) ); 18 memset( flag, -1, sizeof( flag ) ); 19 pcnt = scnt = 0; 20 } 21 22 void match_add( int from, int to ){ 23 ptos[pcnt].to = to; 24 ptos[pcnt].next = ph[from]; 25 ph[from] = pcnt++; 26 27 swap( from, to ); 28 29 stop[scnt].to = to; 30 stop[scnt].next = sh[from]; 31 sh[from] = scnt++; 32 } 33 34 int maxmatch(){ 35 int ans = 0; 36 37 for( int i = 1; i <= n; i++ ){ 38 if( pmatch[i] == -1 ){ 39 queue<int> Q; 40 Q.push( i ); 41 pre[i] = -1; 42 bool ok = false; 43 44 while( !Q.empty() && !ok ){ 45 int pos = Q.front(); Q.pop(); 46 47 for( int k = ph[pos]; k != -1 && !ok; k = ptos[k].next ){ 48 int v = ptos[k].to; 49 if( flag[v] != i ){ 50 flag[v] = i; 51 Q.push( smatch[v] ); 52 if( smatch[v] == -1 ){ 53 ok = true; 54 int tempp = pos, temps = v; 55 while( tempp != -1 ){ 56 int x = pmatch[tempp]; 57 pmatch[tempp] = temps; 58 smatch[temps] = tempp; 59 tempp = pre[tempp]; 60 temps = x; 61 } 62 } 63 else pre[smatch[v]] = pos; 64 } 65 } 66 } 67 if( pmatch[i] != -1) ans++; 68 } 69 } 70 71 return ans; 72 }