题目链接:
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 }