月老的难题
时间限制: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
这道题, 用邻接矩阵TL, 得用邻接表
代码(链式前向星):
#include <stdio.h> #include <string.h> #include <algorithm> #define M 20005 using namespace std; struct node{ int to, next; }s[M]; int head[M], res[555], n; bool vis[555]; int find(int u){ int i; for(i = head[u]; i != -1; i = s[i].next){ int temp = s[i].to; if(!vis[temp]){ vis[temp] = 1; if(res[temp]== 0||find(res[temp])){ res[temp] = u; return true; } } } return false; } int main(){ //freopen("stdin.txt", "r", stdin); int t, k; scanf("%d", &t); while(t --){ scanf("%d%d", &n, &k); memset(res, 0, sizeof(res)); memset(head, -1, sizeof(head)); int a, b; for(int i = 0; i < k; i ++){ scanf("%d%d", &a,&b); s[i].to = b; s[i].next = head[a]; head[a] = i; } int ans = 0; for(int i = 1; i <= n; i ++){ memset(vis, 0, sizeof(vis)); if(find(i)) ++ans; } printf("%d\n", ans); } }
用vector内存有点大
#include <stdio.h> #include <string.h> #include <vector> #define M 555 using namespace std; vector <int > map[M]; int vis[M], res[M]; int n; int find(int a){ int i; for(i = 0; i < map[a].size(); i ++){ if(!vis[map[a][i]]){ vis[map[a][i]] = 1; if(res[map[a][i]] == 0||find(res[map[a][i]])){ res[map[a][i]] = a; return 1; } } } return 0; } int main(){ int t, k; scanf("%d", &t); while(t --){ scanf("%d%d", &n, &k); int i; memset(map, 0, sizeof(map)); memset(res, 0, sizeof(res)); int a, b, ans = 0; for(i = 0; i < k; i ++){ scanf("%d%d", &a, &b); map[a].push_back(b); } for(i = 1; i <= n; i ++){ memset(vis, 0,sizeof(vis)); if(find(i)) ++ans; } printf("%d\n", ans); } return 0; }
时间: 2024-12-20 21:10:53