題意:有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;
}