您的位置:首页 > 其它

CODEVS1022 覆盖 (二分图染色+匈牙利算法)

2014-12-23 20:39 267 查看
先对整幅图进行二分图染色,再跑一遍匈牙利算法。

/* CODEVS1022 */
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

#define maxn 10008

struct edge{
int u,v,next;
}eg[maxn*4];

int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int a[108][108];
int cl[maxn];
int n,m,k,sum,ans;
int last[maxn],l[maxn];
bool pd[maxn];

void dfs(int i,int j,int w)
{
int x,y,k;
cl[a[i][j]]=w;
for (k=0;k<4;k++)
{
int x,y;
x=i+dx[k];
y=j+dy[k];
if ((a[x][y]!=-1)&&!cl[a[x][y]])
dfs(x,y,3-w);
}
}
void add(int u,int v)
{
eg[++sum].u=u;
eg[sum].v=v;
eg[sum].next=last[u];
last[u]=sum;
}
bool find(int u)
{
for (int i=last[u];i;i=eg[i].next)
{
int v=eg[i].v;
if (!pd[v])
{
pd[v]=1;
if ((!l[v])||find(l[v]))
{
l[v]=u;
return 1;
}
}
}
return 0;
}
int main()
{
int i,j,k;
sum=0;
memset(a,-1,sizeof(a));
scanf("%d%d%d",&m,&n,&k);
for (i=1;i<=m;i++)
for (j=1;j<=n;j++)
a[i][j]=(i-1)*n+j;
for (int i=1;i<=k;i++)
{
int x,y;
scanf("%d",&x);
if (x==0) break;
scanf("%d",&y);
a[x][y]=-1;
}
for (i=1;i<=m;i++)
for (j=1;j<=n;j++)
if ((a[i][j]!=-1)&&!cl[a[i][j]])
dfs(i,j,1);
for (i=1;i<=m;i++)
for (j=1;j<=n;j++)
if (cl[a[i][j]]) for (k=0;k<4;k++)
{
int x,y;
x=i+dx[k];
y=j+dy[k];
if ((a[x][y]!=-1)&&cl[a[x][y]])
add(a[i][j],a[x][y]);
}
ans=0;
memset(l,0,sizeof(l));
for (i=1;i<=m*n;i++)
if (cl[i]==1)
{
memset(pd,0,sizeof(pd));
if (find(i)) ans++;
}
//for (i=1;i<=m*n;i++) printf("%d ",l[i]);
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐