【模板】 二分图最大匹配和匈牙利算法

 1 bool dfs(int u)
 2 {
 3     for (iterator_t i = G[u].begin(); i != G[u].end(); ++i) { // 对 u 的每个邻接点
 4         int v = edges[*i].to;
 5         if (!check[v]) {     // 要求不在交替路中
 6             check[v] = true; // 放入交替路
 7             if (matching[v] == -1 || dfs(matching[v])) {
 8                 // 如果是未盖点,说明交替路为增广路,则交换路径,并返回成功
 9                 matching[v] = u;
10                 matching[u] = v;
11                 return true;
12             }
13         }
14     }
15     return false; // 不存在增广路,返回失败
16 }
17 
18 int hungarian()
19 {
20     int ans = 0;
21     memset(matching, -1, sizeof(matching));
22     for (int u=0; u < num_left; ++u) {
23         if (matching[u] == -1) {
24             memset(check, 0, sizeof(check));
25             if (dfs(u))
26                 ++ans;
27         }
28     }
29     return ans;
30 }
31 //https://www.cnblogs.com/wangjunyan/p/5563154.html
32 //上面是临界表,下面邻接矩阵
33 
34 
35 //二分图
36 #define maxn 10//表示x集合和y集合中顶点的最大个数!
37  int nx,ny;//x集合和y集合中顶点的个数
38  int edge[maxn][maxn];//edge[i][j]为1表示ij可以匹配
39  int cx[maxn],cy[maxn];//用来记录x集合中匹配的y元素是哪个!
40  int visited[maxn];//用来记录该顶点是否被访问过!
41  int path(int u)
42  {
43      int v;
44      for(v=0;v<ny;v++)
45      {
46          if(edge[u][v]&&!visited[v])
47          {
48              visited[v]=1;
49             if(cy[v]==-1||path(cy[v]))//如果y集合中的v元素没有匹配或者是v已经匹配,但是从cy[v]中能够找到一条增广路
50              {
51                  cx[u]=v;
52                  cy[v]=u;
53                  return 1;
54              }
55          }
56      }
57      return 0;
58  }
59  int maxmatch()
60  {
61      int res=0;
62      memset(cx,0xff,sizeof(cx));//初始值为-1表示两个集合中都没有匹配的元素!
63      memset(cy,0xff,sizeof(cy));
64      for(int i=0;i<=nx;i++)
65      {
66          if(cx[i]==-1)
67          {
68              memset(visited,0,sizeof(visitited));
69              res+=path(i);
70          }
71      }
72      return res;
73  }
74  //https://www.cnblogs.com/shenben/p/5573788.html

猜你喜欢

转载自www.cnblogs.com/xiaobuxie/p/11391871.html