您的位置:首页 > 其它

POJ-2446 邻接表+二分图匹配

2014-04-05 16:51 239 查看
在孔神的指导下做出了的。。太水了,邻接表都用不好。。。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <vector>
#include <iomanip>
#include <cstdlib>
#include <algorithm>
#define maxn 1050
using namespace std;
int link[maxn];
bool visit[maxn];
int map[maxn][maxn];
int head[maxn],num;
struct bb
{
int e,next;
}ed[maxn*8];
void add(int s,int e)//邻接表
{
ed[num].e=e;
ed[num].next=head[s];
head[s]=num++;
}
bool dfs(int k)//寻找增广路
{
for(int i=head[k];i!=-1;i=ed[i].next)
{
int e=ed[i].e;
if(!visit[e])
{
visit[e]=1;
if(link[e]==-1||dfs(link[e]))
{
link[e]=k;
return true;
}
}
}
return false;
}
int n,m,k;
int fx[4]={0,0,1,-1};
int fy[4]={1,-1,0,0};
int inmap(int x,int y)//判断附近点是否可构成边
{
if(x>=1&&x<=n&&y>=1&&y<=m&&!map[x][y])
{
return 1;
}
return 0;
}
int mapnum[maxn][maxn];
int nn=0;//可覆盖点的个数
void init()//初始化
{
memset(visit,0,sizeof(visit));
memset(map,0,sizeof(map));
memset(link,-1,sizeof(link));
memset(mapnum,0,sizeof(mapnum));
memset(head,-1,sizeof(head));
nn=0;
}
void build()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(map[i][j]==0)
{
mapnum[i][j]=++nn;//给可覆盖点编号
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(!map[i][j])
{
for(int k=0;k<4;k++)//这个点上下左右的4个点点可连成一条边
{
int tx=i+fx[k];
int ty=j+fy[k];
if(inmap(tx,ty))
{
add(mapnum[i][j] ,mapnum[tx][ty]);
}
}
}
}
}
}
int main()
{
int a,b;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
init();//初始化
for(int i=0;i<k;i++)
{
scanf("%d%d",&a,&b);
map[b][a]=1;//有洞的点
}
build();//建图
int ans=0;
for(int i=1;i<=nn;i++)//匈牙利算法
{
memset(visit,0,sizeof(visit));
if(dfs(i))
{
ans++;
}
}
if(nn%2==1||ans!=nn)//如果个数为奇数或者最大匹配数不等于点的个数
{
cout<<"NO"<<endl;
}
else
{
cout<<"YES"<<endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: