题意:给定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 }