版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhanghaoxian1/article/details/83513464
P2071 座位安排
题目背景
公元二零一四年四月十七日,小明参加了省赛,在一路上,他遇到了许多问题,请你帮他解决。
题目描述
已知车上有N排座位,有N*2个人参加省赛,每排座位只能坐两人,且每个人都有自己想坐的排数,问最多使多少人坐到自己想坐的位置。
输入输出格式
输入格式:
第一行,一个正整数N。
第二行至第N*2+1行,每行两个正整数Si1,Si2,为每个人想坐的排数。
输出格式:
一个非负整数,为最多使得多少人满意。
输入输出样例
输入样例#1:
4
1 2
1 3
1 2
1 3
1 3
2 4
1 3
2 3
输出样例#1:
7
说明
对于10%的数据 N≤10
对于30%的数据 N≤50
对于60%的数据 N≤200
对于100%的数据 N≤2000
算法提示:二分图的最大匹配
分析:模板题,给link数组多加一维即可。
代码
#include <cstdio>
#include <string>
#include <cstring>
#define N 50000
using namespace std;
struct arr
{
int to, nxt;
}a[N];
int n,m,ls[N],link[N][3],l;
bool v[N];
void add(int x, int y)
{
a[++l].to = y;
a[l].nxt = ls[x];
ls[x] = l;
}
bool find(int x)
{
for (int i = ls[x]; i; i = a[i].nxt)
if (!v[a[i].to])
{
v[a[i].to] = true;
if (!link[a[i].to][1] || find(link[a[i].to][1]))
{
link[a[i].to][1] = x;
return true;
}
if (!link[a[i].to][2] || find(link[a[i].to][2]))
{
link[a[i].to][2] = x;
return true;
}
}
return false;
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n * 2; i++)
{
int x, y;
scanf("%d%d", &x, &y);
add(i, x);
add(i, y);
}
int ans = 0;
for (int i = 1; i <= n * 2; i++)
{
memset(v, false, sizeof(v));
if (find(i)) ans++;
}
printf("%d\n", ans);
}