最大匹配 

///1. 最大匹配数+ 最大独立集= n + m
///2: 二分图的最小点覆盖 = 最大匹配数
///3: 最小路径覆盖= 最大独立集
///最大独立集是指求一个二分图中最大的一个点集,该点集内的点互不相连。
///最小顶点覆盖是指在二分图中,用最少的点,让所有的边至少和一个点有关联。
///最小路径覆盖是指一个不含圈的有向图G 中,图中的每一个结点仅包含于P 中的一条路径中。

 

http://acm.hdu.edu.cn/showproblem.php?pid=2063

 1 #include<cstdio>
 2 class Bipartite_graph {  ///二分图最大匹配_匈牙利算法_O(MV^3)
 3     static const int MV=5e2+10;///点的个数max(x,y)
 4     bool mat[MV][MV],vis[MV];
 5     int res[MV],n,m,big;///res[]存y部匹配的x部的下标
 6     bool dfs(int a) {
 7         for (int i=0; i<=m; i++) {
 8             if (mat[a][i]&&!vis[i]) {
 9                 vis[i]=true;
10                 if(res[i]==-1||dfs(res[i])) {
11                     res[i]=a;
12                     return true;
13                 }
14             }
15         }
16         return false;
17     }
18 public:
19     void init(int x,int y) {///传入x部和y部点数
20         n=x;
21         m=y;
22         for(int i=0;i<=x;i++){
23             for(int j=0;j<=y;j++){
24                 mat[i][j]=false;
25                 res[j]=-1;
26             }
27         }
28     }
29     void add(int u,int v) {
30         mat[u][v]=true;
31     }
32     int solve() {
33         big=0;
34         for(int i=0; i<=n; i++) {
35             for(int j=0;j<=m;j++) vis[j]=false;
36             if(dfs(i)) big++;
37         }
38         return big;
39     }
40 } g;
41 int main(){
42     int k,n,m,x,y;
43     while(~scanf("%d",&k),k){
44         scanf("%d%d",&n,&m);
45         g.init(n,m);
46         while(k--){
47             scanf("%d%d",&x,&y);
48             g.add(x,y);
49         }
50         printf("%d\n",g.solve());
51     }
52     return 0;
53 }
View Code

相关文章: