我用了vector建图,理论上比邻接表会慢一点,但是因为一个格子最多和四个格子相邻,所以g[x]后面最多有4个数值,由于图的特殊性,不会慢很多,反而方便很多。这题自己写的匈牙利算法效率还算挺高的,用了vector还有31ms,说明我实现的还是挺好的~~!(开始位运算的符号居然写错了。。囧rz=З)
#include<iostream>
#include<vector>
#include<list>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=11111;
const int way[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
vector<int>g[maxn];
int N,M,T,tx,ty,mx,my,temp,t2,sum,nowx,nowy;
int match[maxn];
int map[111][111];
bool vis[maxn];
inline int zz(int x,int y)
{
return x*M+y;
}
inline bool yes(int x,int y)
{
if(x<N && x>=0 && y<M && y>=0)
{
return true;
}
return false;
}
void construct()
{
for(int i=0;i<M*N;i++)
{
g[i].clear();
}
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
if((i+j)&1) //i+j 偶数是x部,奇数是y部。
{
continue;
}
if(map[i][j])
{
continue;
}
for(int k=0;k<4;k++)
{
nowx=i+way[k][0];
nowy=j+way[k][1];
if(!yes(nowx,nowy))
{
continue;
}
if(!map[nowx][nowy])
{
g[ zz(i,j) ].push_back( zz(nowx,nowy) );
}
}
}
}
}
bool dfs(int v)
{
for(int i=0;i<g[v].size();i++)
{
if(vis[g[v][i]])
{
continue;
}
vis[g[v][i]]=true;
if( match[g[v][i]]==-1 || dfs ( match[g[v][i]] ) )
{
match[v]=g[v][i];
match[g[v][i]]=v;
return true;
}
}
return false;
}
void matching()
{
sum=0;
for(int i=0;i<M*N;i++)
{
match[i]=-1;
}
while(true)
{
memset(vis,0,sizeof(vis));
t2=0;
for(int i=0;i<M*N;i++)
{
tx=i/M;
ty=i%M;
if((tx+ty) & 1)
{
continue;
}
if(map[tx][ty])
{
continue;
}
if( -1 != match[i])
{
continue;
}
if( dfs(i) )
{
sum++;
t2=1;
break;
}
}
if(t2==0)
{
break;
}
}
return ;
}
int main()
{
while(scanf("%d%d",&N,&M))
{
if(M==0 && N==0)
{
break;
}
scanf("%d",&T);
memset(map,false,sizeof(map));
for(int i=1;i<=T;i++)
{
scanf("%d%d",&tx,&ty);
map[tx-1][ty-1]=true;
}
construct();
matching();
printf("%d\n",sum);
for(int i=0;i<M*N;i++)
{
if(match[i]==-1)
{
continue;
}
tx=i/M+1;
ty=i%M+1;
if((tx+ty)&1)
{
continue;
}
mx=match[i]/M+1;
my=match[i]%M+1;
printf("(%d,%d)--(%d,%d)\n",tx,ty,mx,my);
}
printf("\n");
}
return 0;
}