題意:有n個大小不等透明的幻燈片(只有輪廓和上面的數字可見)A、B、C、D、E…按順序疊放在一起,現在知道每個幻燈片大小,由於幻燈片是透明的,所以能看到幻燈片上的數字(給出了每個數字的坐標,但不知道這些數字分別屬於哪個幻燈片),現在要你根據當前的已知信息,輸出能夠確定的幻燈片編號和數字的匹配。 思路:很明顯的二分匹配問題,但求的是確定匹配,先求出最大的匹配。然後依次刪除每一條邊,再求其最大匹配,如果最大匹配減小,說明這匹配是確定的。
//168K 0MS #include <stdio.h> #include <string.h> const int M = 30; struct Slide { int x1,x2,y1,y2; } slide[M]; int mat[M][M],link[M],cur[M],vis[M],n; int DFS(int u) { for (int v = 1; v<=n; v ++) { if (!vis[v]&&mat[u][v]) { vis[v] = 1; if(link[v] == -1||DFS(link[v])) { link[v] = u; return 1; } } } return 0; } int MaxMatch() { int u,res = 0; memset(link,-1,sizeof(link)); for (u = 1; u <= n; u ++) { memset (vis,0,sizeof(vis)); if (DFS(u)) res ++; } return res; } int main () { #ifdef LOCAL freopen("in.txt","r",stdin); #endif int i,j,x,y; int cnt = 0; while (scanf ("%d",&n)&&n) { memset (mat,0,sizeof(mat)); 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",&x,&y); for (j = 1; j <= n; j ++) if (x>slide[j].x1&&x<slide[j].x2&&y>slide[j].y1&&y<slide[j].y2) mat[i][j] = 1; } printf ("Heap %d\n",++cnt); int Maxn = MaxMatch(); bool flag = false ; for (j = 1;j <= n;j ++) for (i = 1;i <= n;i ++) { if (!mat[i][j]) continue; mat[i][j] = 0; if (MaxMatch() < Maxn){ flag = true; printf ("(%c,%d) ",'A'+j-1,i); } mat[i][j] = 1; } if (!flag) printf ("none"); printf ("\n\n"); } return 0; }