题解:
二分图最大匹配
建边和第一题差不多
每两个相邻的建边
然后输出方案
代码:
#include<cstring> #include<cmath> #include<algorithm> #include<cstdio> using namespace std; const int N=1005; int vis[N],a[N][N],ans[N],map[N][N],g[N]; int k,n,m,sum,num; struct node{int x,y;}p[N*N]; int dfs(int x) { for (int i=1;i<num;i++) if (!vis[i]&&a[x][i]) { vis[i]=1; if (ans[i]==-1||dfs(ans[i])) { ans[i]=x; return 1; } } return 0; } void match() { sum=0; memset(ans,-1,sizeof(ans)); for(int i=1;i<num;i++) { memset(vis,0,sizeof(vis)); if(dfs(i)) sum++; } } int main() { while (scanf("%d%d",&n,&m)) { if (!n&&!m) break; int u,v; memset(a,0,sizeof(a)); memset(map,0,sizeof(map)); scanf("%d",&k); while (k--) { scanf("%d%d",&u,&v); map[u][v]=1; } num=1; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (map[i][j]==0) { p[num].x=i; p[num++].y=j; } for (int l=1;l<num;l++) for (int j=l+1;j<num;j++) if ((abs(p[l].x-p[j].x)==1&&p[l].y==p[j].y) ||(abs(p[l].y-p[j].y)==1&&p[l].x==p[j].x)) if ((p[l].x+p[l].y)%2==0)a[j][l]=1;else a[l][j]=1; match(); printf("%d ",sum); for (int i=0;i<num;i++) if (ans[i]!=-1) printf("(%d,%d)--(%d,%d) ",p[i].x,p[i].y,p[ans[i]].x,p[ans[i]].y); printf(" "); } return 0; }