POJ-1486 Sorting Slides 二分图or贪心

  题目链接: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 }
posted @ 2012-11-14 15:52  zhsl  阅读(252)  评论(0编辑  收藏  举报