POJ_1486
这个题目相当于判断是否存在唯一的二分图最大匹配的问题,只不过最后即便没有唯一的二分图最大匹配,也将已经匹配好的输出即可。
在匹配的时候采用贪心的策略,如果当前有一个点只连了一条边,那么就一定可以唯一的确定出一个匹配,然后不停的这样找直到找完这样的点为止,剩下的如果还有点没进行匹配,那么剩下的点的匹配就不是唯一的了。
#include<stdio.h> #include<string.h> #define MAXD 30 int N, xM[MAXD], xn[MAXD], yn[MAXD], g[MAXD][MAXD]; struct Digit { int x, y; }digit[MAXD]; struct Slide { int x1, x2, y1, y2; }slide[MAXD]; void init() { int i; for(i = 1; i <= N; i ++) scanf("%d%d%d%d", &slide[i].x1, &slide[i].x2, &slide[i].y1, &slide[i].y2); for(i = 1; i <= N; i ++) scanf("%d%d", &digit[i].x, &digit[i].y); } void solve() { int i, j, k, flag; memset(xn, 0, sizeof(xn)); memset(yn, 0, sizeof(yn)); for(i = 1; i <= N; i ++) for(j = 1; j <= N; j ++) { if(digit[j].x >= slide[i].x1 && digit[j].x <= slide[i].x2 && digit[j].y >= slide[i].y1 && digit[j].y <= slide[i].y2) ++ xn[i], ++ yn[j], g[i][j] = 1; else g[i][j] = 0; } memset(xM, -1, sizeof(xM)); for(;;) { flag = 0; for(i = 1; i <= N; i ++) if(xn[i] == 1) { flag = 1; for(j = 1; j <= N; j ++) if(g[i][j]) break; xM[i] = j, yn[j] = 0; for(k = 1; k <= N; k ++) if(g[k][j]) g[k][j] = 0, -- xn[k]; } for(i = 1; i <= N; i ++) if(yn[i] == 1) { flag = 1; for(j = 1; j <= N; j ++) if(g[j][i]) break; xM[j] = i, xn[j] = 0; for(k = 1; k <= N; k ++) if(g[j][k]) g[j][k] = 0, -- yn[k]; } if(!flag) break; } flag = 0; for(i = 1; i <= N; i ++) if(xM[i] != -1) { if(flag) printf(" "); else flag = 1; printf("(%c,%d)", 'A' + i - 1, xM[i]); } if(flag == 0) printf("none"); printf("\n"); } int main() { int t = 0; while(scanf("%d", &N), N) { init(); printf("Heap %d\n", ++ t); solve(); printf("\n"); } return 0; }