月老的难题
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘。
现在,由于一些原因,部分男孩与女孩可能结成幸福的一家,部分可能不会结成幸福的家庭。
现在已知哪些男孩与哪些女孩如果结婚的话,可以结成幸福的家庭,月老准备促成尽可能多的幸福家庭,请你帮他找出最多可能促成的幸福家庭数量吧。
假设男孩们分别编号为1~n,女孩们也分别编号为1~n。
-
输入
-
第一行是一个整数T,表示测试数据的组数(1<=T<=400)
每组测试数据的第一行有两个整数n,K,其中男孩的人数与女孩的人数都是n。(n<=500,K<=10 000)
随后的K行,每行有两个整数i,j表示第i个男孩与第j个女孩有可能结成幸福的家庭。(1<=i,j<=n)
输出
- 对每组测试数据,输出最多可能促成的幸福家庭数量 样例输入
-
1 3 4 1 1 1 3 2 2 3 2
样例输出
-
2
/* 题目有坑,邻接矩阵会超时,结果改成临界表之后wa了一次,重写了一次,过了。 Time:2014-9-16 17:03 */ #include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; const int MAX=510; vector<vector<int> >G(MAX); bool vis[MAX]; int linker[MAX]; int N,M; bool DFS(int u){ for(int i=0;i<G[u].size();i++){ int v=G[u][i]; if(!vis[v]){ vis[v]=true; if(linker[v]==-1||DFS(linker[v])){ linker[v]=u; return true; } } } return false; } int hungary(){ memset(linker,-1,sizeof(linker)); int ans=0; for(int i=1;i<=N;i++){ memset(vis,0,sizeof(vis)); if(DFS(i)) ans++; } return ans; } void solve(){ int T; scanf("%d",&T); while(T--){ int a,b; scanf("%d%d",&N,&M); while(M--){ scanf("%d%d",&a,&b); G[a].push_back(b); } printf("%d\n",hungary()); for(int i=0;i<=N;i++) if(G[i].size())G[i].clear(); } } int main(){ solve(); return 0; }
-
第一行是一个整数T,表示测试数据的组数(1<=T<=400)