一、二分图

1、最大匹配数 = 最大流 = 最小割 = 最小点集覆盖 = 总点数 - 最大独立集

2、KM算法(最佳完美匹配

 1 int mat[MAXN][MAXN], slack[MAXN], Lx[MAXN], Ly[MAXN], left[MAXN];   
 2 bool S[MAXN], T[MAXN];   
 3        
 4 bool dfs(int i)   
 5 {   
 6     S[i] = true;   
 7     for(int j = 1; j <= n; ++j) if(!T[j]) {   
 8         int t = Lx[i] + Ly[j] - mat[i][j];   
 9         if(t == 0){   
10             T[j] = true;   
11             if(!left[j] || dfs(left[j])){   
12                 left[j] = i;   
13                 return true;   
14             }   
15         }   
16         else slack[j] = min(slack[j],t);   
17     }   
18     return false;   
19 }   
20        
21 void update()   
22 {   
23     int a = INF;   
24     for(int i = 1; i <= n; ++i) if(!T[i])   
25         a = min(slack[i],a);   
26     for(int i = 1; i <= n; ++i){   
27         if(S[i]) Lx[i] -= a;   
28         if(T[i]) Ly[i] += a; else slack[i] -= a;   
29     }   
30 }   
31        
32 int KM()   
33 {   
34     for(int i = 1; i <= n; ++i){   
35         Lx[i] = Ly[i] = left[i] = 0;   
36         for(int j = 1; j <= n; ++j) Lx[i] = max(Lx[i],mat[i][j]);   
37     }   
38     for(int i = 1; i <= n; ++i){   
39         for(int j = 1; j <= n; ++j) slack[j] = INF;   
40         while(1){   
41             for(int j = 1; j <= n; ++j) S[j] = T[j] = 0;   
42             if(dfs(i)) break; else update();   
43         }   
44     }   
45     int ans = 0;   
46     for(int i = 1; i <=n; ++i) ans += Lx[i] +Ly[i];   
47     return ans;   
48 }
View Code

相关文章: