#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
vector<int> land[100];
int link[100];
bool vis[100];
int g[110][110];
bool vis2[100];
int pond[100];
int n,m,k;
bool can(int x)
{
int len = land[x].size();
for(int i = 0;i < len;i ++)
{
int t = land[x].at(i);
if(!vis[t])
{
vis[t] = true;
if(link[t] == -1 || can(link[t]))
{
link[t] = x;
return true;
}
}
}
return false;
}
int maxmatch(int count)
{
int num = 0;
memset(link,-1,sizeof(link));
for(int i = 1;i <= count;i ++)
{
memset(vis,false,sizeof(vis));
if(can(i))
num ++;
}
/*for(int i = 1;i <= count;i ++)
{
if(link[i] != -1)
printf("link[%d]:%d\n",i,link[i]);
}*/
return num;
}
void print()
{
memset(vis2,false,sizeof(vis2));
for(int i = 1;i <= n;i ++)
{
for(int j = 1;j <= m;j ++)
{
if(g[i][j]&&!vis2[g[i][j]]&&link[g[i][j]] != -1&&!vis2[link[g[i][j]]])
{
int ax = (g[i][j] + pond[g[i][j]] - 1)/m + 1;//pond的作用就在这里,将编号还原为矩形的一格一格编号
int ay = (g[i][j] + pond[g[i][j]]-1)%m+1;
int bx = (link[g[i][j]] + pond[link[g[i][j]]] - 1)/m +1;
int by = (link[g[i][j]] + pond[link[g[i][j]]]-1) % m+1;
vis2[g[i][j]] = true;//将访问过的点标记
vis2[link[g[i][j]]] = true;
printf("(%d,%d)--(%d,%d)\n",ax,ay,bx,by);
}
}
}
printf("\n");
}
int main()
{
while(scanf("%d%d",&n,&m),n || m)
{
memset(g,-1,sizeof(g));
memset(pond,0,sizeof(pond));
scanf("%d",&k);
for(int i = 0;i < 55;i ++)
{
land[i].clear();
}
for(int i = 0;i < k;i ++)
{
int a,b;
scanf("%d%d",&a,&b);
g[a][b] = 0;
}
int t = 0;
int count = 1;
for(int i = 1;i <= n;i ++)
{
for(int j = 1;j <= m;j ++)
{
if(g[i][j] == 0)
{
t ++;
}
else
{
pond[count] = t;//记录land前面pond的个数
//printf("pond[%d]:%d\n",count,t);
g[i][j] = count ++;//给每个land编号
}
}
}
for(int i = 1;i <= n;i ++)
{
for(int j = 1;j <= m;j ++)
{
//printf("%d ",g[i][j]);
if(g[i][j] != 0)
{
if(i-1>0&&g[i-1][j] != 0)
{
land[g[i][j]].push_back(g[i-1][j]);
}
if(i +1 <=m && g[i+1][j] != 0)
{
land[g[i][j]].push_back(g[i + 1][j]);
}
if(j - 1> 0&& g[i][j -1] != 0)
{
land[g[i][j]].push_back(g[i][j-1]);
}
if(j + 1 <= n&&g[i][j + 1] != 0)
{
land[g[i][j]].push_back(g[i][j+1]);
}
}
}
//printf("\n");
}
printf("%d\n",maxmatch(count - 1) / 2);
print();
}
return 0;
}
一A,太兴奋了,(*^__^*) 嘻嘻……而且效率还蛮不错滴 15MS 292K。
二分匹配来着,只不过题目要求我们输出匹配的方案
本来之前打算来个暴力的,但是N*M可达1万,然后嘞,题目又说N*M-K<=50,就改变策略了,给不是池塘的land编号,并记录每个land前面的池塘数目(记录池塘的数目是方便输出的,题目要求我们输出匹配的行与列,反正land也就50个),这样编号的land最多也就50个了。
可是就是还有人0ms过的,(~ o ~)~zZ崇拜
浙公网安备 33010602011771号