Punching Power Gym - 101670J (二分图最大独立点集匈牙利算法(模板))
题目大意与解题思路
给n[1,2000 ]个点的二维平面坐标,选一个最大的点的集合,要求其中任意两点距离不能大于1.3。
1.3是一个很特别条件,因为给出的点都是整数点,所以就是上下相邻和左右相邻的不能同时出现,这就是一个二分图,同一条反斜线上的点的特征是横纵坐标值之和相同,所以按横纵坐标值和的奇偶性可以分成两部分。
二分图的最大独立点集数量就是(总数-最大匹配)。
AC代码
#include <bits/stdc++.h>
#define LL long long
using namespace std;
#define maxn 2007
const int INF=0x3f3f3f3f;
struct node
{
int x,y;
}a[maxn];
int cmp(node a,node b)
{
return a.x+a.y<b.x+b.y;
}
vector <int> edge[maxn];
int vis[maxn];
int match[maxn];
int finded(int x)
{
int i,j;
for(i=0;i<edge[x].size();i++)
{
j=edge[x][i];
if(!vis[j])
{
vis[j]=1;
if(match[j]==-1||finded(match[j]))
{
match[j]=x;
return 1;
}
}
}
return 0;
}
int main()
{
int n,i,j,k;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
{
edge[i].clear();
scanf("%d%d",&a[i].x,&a[i].y);
}
sort(a+1,a+1+n,cmp);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)==1)
{
edge[i].push_back(j);
edge[j].push_back(i);
}
}
match[i]=-1;
}
int maxMatch=0;
for(i=1;i<=n;i++)
{
if((a[i].x+a[i].y)%2)
{
memset(vis,0,(n+1)*sizeof(int));
if(finded(i))
maxMatch++;
}
}
printf("%d\n",n-maxMatch);
}
return 0;
}