#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崇拜