题意:给定n张幻灯片,每张都有数字,由于幻灯片是透明的,所以不能确定每个数字指的是哪个,于是问你能确定哪些。

题解:二分匹配,然后再对每一个点检验,即找到它当前未匹配的对象且能够与它进行匹配的,将他们进行匹配,然后找因此而失配的那个点的增广路,能找到就说明不能确定。

View Code
  1 #include<cstdio>
  2 #include<cstring>
  3 using namespace std;
  4 int link[30],rlink[30],n;
  5 bool g[30][30],chk[30];
  6 bool findpath(int x)
  7 {
  8     for(int y=0;y<n;y++)
  9     {
 10         if(g[x][y]&&!chk[y])
 11         {
 12             chk[y]=true;
 13             if(rlink[y]==-1||findpath(rlink[y]))
 14             {
 15                 rlink[y]=x;
 16                 link[x]=y;
 17                 return true;
 18             }
 19         }
 20     }
 21     return false;
 22 }
 23 int maxmatch()
 24 {
 25     memset(link,-1,sizeof(link));
 26     memset(rlink,-1,sizeof(rlink));
 27     int ret=0;
 28     for(int x=0;x<n;x++)
 29     {
 30         memset(chk,false,sizeof(chk));
 31         if(findpath(x))
 32             ret++;
 33     }
 34     return ret;
 35 }
 36 struct Rec
 37 {
 38     int minx,maxx,miny,maxy;
 39 }rec[30];
 40 int main()
 41 {
 42     int ca=0;
 43     while(scanf("%d",&n)&&n)
 44     {
 45         if(ca)
 46             printf("\n");
 47         memset(g,false,sizeof(g));
 48         for(int i=0;i<n;i++)
 49             scanf("%d%d%d%d",&rec[i].minx,&rec[i].maxx,&rec[i].miny,&rec[i].maxy);
 50         for(int i=0;i<n;i++)
 51         {
 52             int x,y;
 53             scanf("%d%d",&x,&y);
 54             for(int j=0;j<n;j++)
 55             {
 56                 if(x>=rec[j].minx&&x<=rec[j].maxx&&y>=rec[j].miny&&y<=rec[j].maxy)
 57                 {
 58                     g[j][i]=true;
 59                 }
 60             }
 61         }
 62         maxmatch();
 63         printf("Heap %d\n",++ca);
 64         bool flag=true,ths;
 65         for(int i=0;i<n;i++)
 66         {
 67             int t=link[i],rl;
 68             ths=true;
 69             for(int j=0;j<n;j++)
 70             {
 71                 if(t!=j&&g[i][j])
 72                 {
 73                     rl=rlink[j];
 74                     link[rl]=-1;
 75                     rlink[j]=i;
 76                     link[i]=j;
 77                     rlink[t]=-1;
 78                     memset(chk,false,sizeof(chk));
 79                     chk[j]=true;
 80                     if(findpath(rl))
 81                     {
 82                         ths=false;
 83                         break;
 84                     }
 85                     rlink[j]=rl;
 86                     link[rl]=j;
 87                     link[i]=t;
 88                     rlink[t]=i;
 89                 }
 90             }
 91             if(ths)
 92             {
 93                 if(!flag)
 94                     printf(" ");
 95                 flag=false;
 96                 printf("(%c,%d)",'A'+i,link[i]+1);
 97             }
 98         }
 99         if(flag)
100             printf("none");
101         printf("\n");
102     }
103     return 0;
104 }