原题链接 hdu4619 warm up 2
以前很少做图论的题,一般要是看出来事图论,肯定不会让我敲,这是在多校联合第二场上的题,最近看了看二分匹配的,
然后就yy了一下,第一次脱离模板 写匈牙利算法,还好1A,
对于这种格子覆盖的题,一般是把格子分成两个集合,任意相邻的格子必定不在一个集合中,我一般把原图点(x,y)满足 ((x%2==0&&y%2==0)||(x%2==1&&y%2==1))当做二分图边的始点,它一般是可以向上下左右连边,,建好图后就是 裸地匹配了。
新手代码 慎入
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define N 11000
using namespace std;
vector<int> map[N];
int n,m;
int cx[N],cy[N];
bool vis[N];
void init()
{
int x,y,tmp1,tmp2;
for(int i=0;i<n;i++)
{
scanf("%d%d",&x,&y);
tmp1=x*102+y;
tmp2=(x+1)*102+y;
if((x%2==0&&y%2==0)||(x%2==1&&y%2==1))
map[tmp1].push_back(tmp2);
else
map[tmp2].push_back(tmp1);
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
tmp1=x*102+y;
tmp2=x*102+y+1;
if((x%2==0&&y%2==0)||(x%2==1&&y%2==1))
map[tmp1].push_back(tmp2);
else
map[tmp2].push_back(tmp1);
}
}
int findpath(int u)
{
int len=map[u].size();
for(int j=0;j<len;j++)
{
if(!vis[map[u][j]])
{
vis[map[u][j]]=true;
if(cy[map[u][j]]==-1||findpath(cy[map[u][j]]))
{
cx[u]=map[u][j];
cy[map[u][j]]=u;
return 1;
}
}
}
return 0;
}
int match()
{
int res=0;
memset(cx,-1,sizeof(cx));
memset(cy,-1,sizeof(cy));
for(int i=0;i<N;i++)
{
int x=i/102;
int y=i%102;
if(((x%2==0&&y%2==0)||(x%2==1&&y%2==1))&&cx[i]==-1)
{
memset(vis,false,sizeof(vis));
res+=findpath(i);
}
}
return res;
}
int main()
{
// freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m)&&n)
{
for(int i=0;i<N;i++)
map[i].clear();
init();
printf("%d\n",match());
}
}