题目链接:http://poj.org/problem?id=1486
这种题目一般都会想到贪心的做法吧,很直接也很方便。即直接找出度或入度为1的节点,然后删除,再接着找。。。
还有一种做法就是利用二分图的性质,首先求出最大匹配。当然这个最大匹配不是最终答案,因为可能匹配中会有不唯一的匹配,所以我们要求的就是一个唯一的且最大的匹配。那么我们可以在重新求一次增广路,把已经匹配的边依次删除,看当前匹配点还能不能找到增广路,如果能找到,那么这个点的匹配点就不唯一了,也就是非必须边,否则就是必须边。
贪心算法:
1 //STATUS:G++_AC_0MS_796KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector> 10 #include<queue> 11 #include<stack> 12 using namespace std; 13 #define LL long long 14 #define Max(a,b) ((a)>(b)?(a):(b)) 15 #define Min(a,b) ((a)<(b)?(a):(b)) 16 #define mem(a,b) memset(a,b,sizeof(a)) 17 #define lson l,mid,rt<<1 18 #define rson mid+1,r,rt<<1|1 19 const int MAX=120,INF=200000000; 20 struct Node{ 21 int x,y; 22 }nod[MAX]; 23 struct Square{ 24 int x1,y1,x2,y2; 25 }squ[MAX]; 26 27 int lef[MAX][MAX],righ[MAX][MAX],ans[MAX]; 28 int n; 29 30 void getG() 31 { 32 int i,j; 33 mem(lef,0); 34 mem(righ,0); 35 for(i=1;i<=n;i++){ 36 for(j=1;j<=n;j++){ 37 if(nod[j].x>squ[i].x1&&nod[j].x<squ[i].x2 38 && nod[j].y>squ[i].y1&&nod[j].y<squ[i].y2){ 39 lef[i][0]++; 40 righ[j][0]++; 41 lef[i][j]=righ[j][i]=1; 42 } 43 } 44 } 45 } 46 47 void greedy() 48 { 49 int i,j,flag=1,cou=0,k; 50 mem(ans,0); 51 while(flag){ 52 flag=0; 53 for(i=1;i<=n;i++){ 54 if(lef[i][0]==1){ 55 flag=1; 56 for(j=1;j<=n && !lef[i][j];j++); 57 ans[i]=j; 58 for(k=1;k<=n;k++){ 59 if(lef[k][j])lef[k][0]--,lef[k][j]=0; 60 if(righ[k][i])righ[k][0]--,righ[k][i]=0; 61 } 62 lef[i][0]=0; 63 righ[j][0]=0; 64 } 65 if(righ[i][0]==1){ 66 flag=1; 67 for(j=1;j<=n && !righ[i][j];j++); 68 ans[j]=i; 69 for(k=1;k<=n;k++){ 70 if(lef[k][i])lef[k][0]--,lef[k][i]=0; 71 if(righ[k][j])righ[k][0]--,righ[k][j]=0; 72 } 73 lef[j][0]=0; 74 righ[i][0]=0; 75 } 76 } 77 } 78 } 79 80 int main() 81 { 82 // freopen("in.txt","r",stdin); 83 int i,j,k=1,flag; 84 while(~scanf("%d",&n) && n) 85 { 86 for(i=1;i<=n;i++) 87 scanf("%d%d%d%d",&squ[i].x1,&squ[i].x2,&squ[i].y1,&squ[i].y2); 88 for(i=1;i<=n;i++) 89 scanf("%d%d",&nod[i].x,&nod[i].y); 90 91 getG(); 92 greedy(); 93 94 printf("Heap %d\n",k++); 95 for(i=1,flag=0;i<=n;i++){ 96 if(ans[i]){ 97 if(flag)printf(" (%c,%d)",i+'A'-1,ans[i]); 98 else { 99 flag=1; 100 printf("(%c,%d)",i+'A'-1,ans[i]); 101 } 102 } 103 } 104 105 if(!flag) printf("none"); 106 putchar('\n'); 107 putchar('\n'); 108 } 109 return 0; 110 }
二分图匹配:
1 //STATUS:G++_AC_0MS_744KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector> 10 #include<queue> 11 #include<stack> 12 using namespace std; 13 #define LL long long 14 #define Max(a,b) ((a)>(b)?(a):(b)) 15 #define Min(a,b) ((a)<(b)?(a):(b)) 16 #define mem(a,b) memset(a,b,sizeof(a)) 17 #define lson l,mid,rt<<1 18 #define rson mid+1,r,rt<<1|1 19 const int MAX=120,INF=200000000; 20 struct Node{ 21 int x,y; 22 }nod[MAX]; 23 struct Square{ 24 int x1,y1,x2,y2; 25 }squ[MAX]; 26 27 int g[MAX][MAX],vis[MAX],y[MAX],ans[MAX]; 28 int n,have; 29 30 void getG() 31 { 32 int i,j; 33 for(i=0;i<n;i++){ 34 for(j=0;j<n;j++){ 35 if(nod[j].x>squ[i].x1&&nod[j].x<squ[i].x2 36 && nod[j].y>squ[i].y1&&nod[j].y<squ[i].y2) 37 g[i][j]=1; 38 } 39 } 40 } 41 42 int match(int u) 43 { 44 int v; 45 for(v=0;v<n;v++){ 46 if(g[u][v] && !vis[v]){ 47 vis[v]=1; 48 if(y[v]==-1 || match(y[v])){ 49 if(have)y[v]=u; 50 return 1; 51 } 52 } 53 } 54 return 0; 55 } 56 57 int main() 58 { 59 // freopen("in.txt","r",stdin); 60 int i,j,k=1,flag,t; 61 while(~scanf("%d",&n) && n) 62 { 63 flag=1; 64 mem(y,-1); 65 mem(ans,-1); 66 mem(g,0); 67 68 for(i=0;i<n;i++) 69 scanf("%d%d%d%d",&squ[i].x1,&squ[i].x2,&squ[i].y1,&squ[i].y2); 70 for(i=0;i<n;i++) 71 scanf("%d%d",&nod[i].x,&nod[i].y); 72 73 getG(); 74 have=1; 75 for(i=0;i<n;i++){ 76 mem(vis,0); 77 match(i); 78 } 79 80 have=0; 81 for(i=0;i<n;i++){ 82 if(y[i]!=-1){ 83 mem(vis,0); 84 t=y[i]; 85 g[t][i]=0; 86 y[i]=-1; 87 if(!match(t)) 88 ans[t]=i; 89 g[t][i]=1; 90 y[i]=t; 91 } 92 } 93 94 printf("Heap %d\n",k++); 95 for(i=0;i<n;i++){ 96 if(ans[i]!=-1){ 97 if(flag){ 98 flag=0; 99 printf("(%c,%d)",i+'A',ans[i]+1); 100 } 101 else printf(" (%c,%d)",i+'A',ans[i]+1); 102 } 103 } 104 if(flag)printf("none"); 105 printf("\n\n"); 106 } 107 return 0; 108 }