1、hdu 2444 The Accomodation of Students(判断二分图+最大匹配)(匈牙利模板)

  题意:一共有n个学生,m对关系:A认识B。问能否将所有的人分成两批,每批之间的人都互相认识,如果可以,输出每批的人数。即判断是否为二分图,以及求二分图的最大匹配。

  思路:判断是否为二分图(DFS或BFS);求二分图的最大匹配:匈牙利算法。

 1 #include<iostream>
 2 #include<queue>
 3 using namespace std;
 4 int n,m;
 5 const int maxn = 210;//x集合和y集合总最大的点数
 6 bool mp[maxn][maxn];//1表示该ij可以匹配
 7 int cx[maxn];//记录x集合中匹配的y元素是哪一个
 8 int cy[maxn];//记录y集合中匹配的x元素是哪一个
 9 int vis[maxn];//标记该顶点是否访问过
10 int cntx;
11 bool dfs(int u)
12 {
13     for (int v = 1; v <= n; v++)//两个集合内共有n个元素
14     {
15         if (mp[u][v] && !vis[v])
16         {
17             vis[v] = 1;
18             if (cy[v] == -1 || dfs(cy[v]))//)//如果y集合中的v元素没有匹配或者是v已经匹配,但是从cy[v]中能够找到一条增广路
19             {
20                 cx[u] = v; cy[v] = u;
21                 return 1;
22             }
23         }
24     }
25     return 0;
26 }
27 int maxmatch()//匈牙利算法主函数
28 {
29     int ans = 0;
30     memset(cx, 0xff, sizeof cx);//初始值为-1表示两个集合中都没有匹配的元素!
31     memset(cy, 0xff, sizeof cy);
32     for (int i = 1; i <= n; i++)
33         if (cx[i] == -1)//如果i未匹配
34         {
35             memset(vis, 0, sizeof(vis));
36             ans += dfs(i);
37         }
38     return ans/2;//对两个部里的都匹配了,这样就相当于匹配了两次了  
39 }
40 bool istwo()
41 {//判断是否为二分图
42     queue<int>q;
43     memset(vis, 0, sizeof(vis));
44     q.push(1);
45     vis[1] = true;
46     while (!q.empty())
47     {
48         int u = q.front();
49         q.pop();
50         for (int i = 1; i <= n; i++)
51         {
52             if (mp[u][i])
53             {
54                 if (vis[i] == 0)
55                 {
56                     if (vis[u] == 1) vis[i] = 2;
57                     else vis[i] = 1;
58                     q.push(i);
59                 }
60                 else
61                 {
62                     if (vis[i] == vis[u]) return false;
63                 }
64             }
65         }
66     }
67     return true;
68 }
69 int main()
70 {
71     while (~scanf("%d%d", &n, &m))
72     {
73         memset(mp ,0, sizeof(mp));
74         while (m--)
75         {
76             int a, b;
77             scanf("%d%d", &a, &b);
78             mp[a][b] = mp[b][a] = 1;
79         }
80         if (!istwo()|| n == 1)
81         {
82             printf("No\n");
83         }
84         else
85         {
86             int ans = maxmatch();
87             printf("%d\n", ans);
88         }
89     }
90 
91     return 0;
92 }
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-08-31
  • 2022-12-23
  • 2021-11-17
  • 2022-12-23
  • 2021-08-23
  • 2021-08-16
猜你喜欢
  • 2022-12-23
  • 2021-10-10
  • 2022-01-01
  • 2021-11-07
  • 2022-12-23
相关资源
相似解决方案