POJ-1274 The Perfect Stall---二分图模板

题目链接:

https://vjudge.net/problem/POJ-1274

题目大意:

有n个奶牛和m个谷仓,现在每个奶牛有自己喜欢去的谷仓,并且它们只会去自己喜欢的谷仓吃东西,问最多有多少奶牛能够吃到东西

输入第一行给出n与m接着n行每行第一个数代表这个奶牛喜欢的谷仓的个数P,后面接着P个数代表这个奶牛喜欢哪个谷仓

思路:

二分图模板

 1 #include<iostream>
 2 #include<vector>
 3 #include<cstring>
 4 #include<queue>
 5 using namespace std;
 6 const int maxn = 300 + 10;
 7 const int INF = 0x3f3f3f3f;
 8 int Map[maxn][maxn];
 9 int cx[maxn], cy[maxn];
10 //cx[i]表示与x部的点i匹配的y部的点的编号
11 //cy[i]表示与y部的点i匹配的x部的点的编号
12 bool vis[maxn];//标记y部的点是否加入增广路
13 int cntx, cnty;//x部点的数目和y部点的数目
14 
15 bool dfs(int u)//dfs进入的都是x部的点
16 {
17     for(int v = 1; v <= cnty; v++)//枚举y部的点
18     {
19         if(Map[u][v] && !vis[v])//存在边,并且还未加入增广路
20         {
21             vis[v] = 1;//标记加入增广路
22             //如果Y部的点v还未被匹配
23             //或者已经被匹配了,但是可以从v点原来匹配的cy[v]找到一条增广路
24             //说明这条路就可是一个正确的匹配
25             if(cy[v] == -1 || dfs(cy[v]))
26             {
27                 cx[u] = v;
28                 cy[v] = u;
29                 return true;
30             }
31         }
32     }
33     return false;//不能匹配
34 }
35 int maxmatch()//匈牙利算法找最大匹配
36 {
37     int ans = 0;
38     memset(cx, -1, sizeof(cx));
39     memset(cy, -1, sizeof(cy));//初始化均未匹配
40     for(int i = 1; i <= cntx; i++)//枚举x部的点
41     {
42         if(cx[i] == -1)//还未匹配,寻找从i点出发是否存在增广路
43         {
44             memset(vis, 0, sizeof(vis));
45             ans += dfs(i);
46         }
47     }
48     return ans;
49 }
50 int main()
51 {
52     while(cin >> cntx >> cnty)
53     {
54         memset(Map, 0, sizeof(Map));
55         int v, t;
56         for(int u = 1; u <= cntx; u++)
57         {
58             cin >> t;
59             while(t--)
60             {
61                 cin >> v;
62                 Map[u][v] = 1;
63             }
64         }
65         cout<<maxmatch()<<endl;
66         //for(int i = 1; i <= cntx; i++)cout<<i<<" "<<cx[i]<<endl;
67     }
68 }
原文地址:https://www.cnblogs.com/fzl194/p/8871422.html