题目:http://www.lightoj.com/volume_showproblem.php?problem=1184
题意:有n个男人和m个女人相亲(我这里的n,m和题目中正好相反),问最多可以配成多少对,其中配对的条件为:双方身高之差不超过12,年龄之差不超过5,同时结婚或离婚。
思路:根据要求连边建图即可,跑一下匈牙利算法就是答案,简单题
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 110;
struct edge
{
int to, next;
}g[N*N];
int head[N], match[N];
int nx, ny, cnt, cas = 0;
bool used[N];
void add_edge(int v, int u)
{
g[cnt].to = u, g[cnt].next = head[v], head[v] = cnt++;
}
bool dfs(int v)
{
for(int i = head[v]; i != -1; i = g[i].next)
{
int u = g[i].to;
if(! used[u])
{
used[u] = true;
if(match[u] == -1 || dfs(match[u]))
{
match[u] = v;
return true;
}
}
}
return false;
}
int hungary()
{
int res = 0;
memset(match, -1, sizeof match);
for(int i = 1; i <= nx; i++)
{
memset(used, 0, sizeof used);
if(dfs(i)) res++;
}
return res;
}
int main()
{
int t, n, m;
int h1[N], h2[N], a1[N], a2[N], d1[N], d2[N];
scanf("%d", &t);
while(t--)
{
cnt = 0;
memset(head, -1, sizeof head);
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
scanf("%d%d%d", &h1[i], &a1[i], &d1[i]);
for(int i = 1; i <= m; i++)
scanf("%d%d%d", &h2[i], &a2[i], &d2[i]);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
if(abs(h1[i] - h2[j]) <= 12 && abs(a1[i] - a2[j]) <= 5 && d1[i] == d2[j])
add_edge(i, j);
nx = n, ny = m;
printf("Case %d: %d\n", ++cas, hungary());
}
return 0;
}