地址
点击打开链接
这个题目的特别行在于如何区分两个集合,做到二分。
自己按照以前的格式写了一个,很容易理解,每次都找四个方向。代码如下,很容易理解。
#include<iostream>
#include<string.h>
#include<cstdio>
#define MAX 105
using namespace std;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int Map[MAX][MAX];
int Vis[MAX][MAX];
int n, m ,k;
struct Node{
int x ;
int y ;
};
Node nodes[MAX][MAX];
bool dfs(Node a)
{
Node temp ;
for(int i = 0 ; i <4 ; i ++ )
{
temp.x=dir[i][0]+a.x;
temp.y=dir[i][1]+a.y;
if(temp.x>=1&&temp.x<=n&&temp.y>=1&&temp.y<=m)
{
if(!Vis[temp.x][temp.y]&&Map[temp.x][temp.y])
{
Vis[temp.x][temp.y]=1 ;
if(!nodes[temp.x][temp.y].x||dfs(nodes[temp.x][temp.y]))//一开始这个地方写成了dfs(temp)了
{
nodes[temp.x][temp.y]=a ;
return true ;
}
}
}
}
return false ;
}
int hungary(){
int ans= 0 ;
Node temp ;
for(int i = 1 ; i<=n ; i ++)
{
for(int j =1 ; j <= m ; j ++)
{
if(((i+j)&1)&&Map[i][j])
{
memset(Vis,0,sizeof(Vis));
temp.x = i ; temp.y = j;
if(dfs(temp))
ans+=1;
}
}
}
return ans ;
}
int main(){
int a, b ,i,j;
while(~scanf("%d%d",&n,&m)&&m+n!=0)
{
scanf("%d",&k);
memset(Map,1,sizeof(Map));
while(k--)
{
scanf("%d%d",&a,&b);
Map[a][b]=0;
}
memset(nodes,0,sizeof(nodes));
int ans = hungary();
printf("%d\n",ans);
for(i = 1 ; i <= n ; i ++)
{
for(j = 1 ; j <= m ; j++)
{
if(nodes[i][j].x)
{
printf("(%d,%d)--(%d,%d)\n",nodes[i][j].x,nodes[i][j].y,i,j);//这个答案不唯一,可能和样例给出的答案不一致,很正常,输出的顺序也没有要求。
}
}
}
printf("\n");
}
}