hdu 1507 Uncle Tom's Inherited Land(二分图匹配的活用 c语言版)
时间:2011-05-08 来源:银志圆
题意:
给定一个n*m的矩阵,黑点代表无效点,两个相邻白点为一组
问最多能找到多少组
解题:
此题很容易想到2分匹配,将矩形建成二分图,列行和为奇的为左边,列行和为偶的为右边;
不过要注意的是不能用邻接矩阵形式的二分图。
参考 The_One1989的空间
#include<stdio.h>
#include<string.h>
#define N 10211
#define M 101
int G[M][M],g[N],len[N],map[N][5],vis[N],link[N],n,m,s;
int move[4][2]={-1,0,1,0,0,1,0,-1};
int can(int t)
{
int i;
for(i=0;i<len[t];i++)
{
int v=map[t][i];
if(!vis[v])
{
vis[v]=1;
if(link[v]==-1||can(link[v]))
{
link[v]=t;
return 1;
}
}
}
return 0;
}
int getans()
{
int i,ans=0;
memset(link,-1,sizeof(link));
for(i=0;i<len[0];i++)
{
memset(vis,0,sizeof(vis));
if(can(g[i])) ans++;
}
return ans;
}
int main()
{
while(scanf("%d%d",&n,&m),n||m)
{
scanf("%d",&s);
int x,y,i,j,k,a,b,x1,y1;
memset(G,0,sizeof(G));
memset(len,0,sizeof(len));
while(s--)
{
scanf("%d%d",&x,&y);
G[x][y]=1;
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)if(((i+j)%2)&&!G[i][j])
{
a=(i-1)*m+j;
int flag=0;
for(k=0;k<4;k++)
{
x=i+move[k][0];
y=j+move[k][1];
if(x>0&&x<=n&&y>0&&y<=m&&!G[x][y])
{
flag=1;
b=(x-1)*m+y;
map[a][len[a]++]=b;
}
}
if(flag)
{
g[len[0]++]=a;
}
}
}
printf("%d\n",getans());
for(i=1;i<=n*m;i++)if(link[i]!=-1)
{
x=(i-1)/m+1;/*十进制与二维坐标的转换 谨记*/
y=(i-1)%m+1;
x1=(link[i]-1)/m+1;
y1=(link[i]-1)%m+1;
/*输出路径*/
printf("(%d,%d)--(%d,%d)\n",x,y,x1,y1);
}
printf("\n");
}
return 0;
}
相关阅读 更多 +
排行榜 更多 +










