zoukankan      html  css  js  c++  java
  • POJ1486 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 }
  • 相关阅读:
    Codevs 4633 [Mz]树链剖分练习
    Codevs 2460 == BZOJ 1036 树的统计
    洛谷 P1038 神经网络
    POJ 1062 昂贵的聘礼
    POJ 1459 Power Network
    POJ 1149 PIGS
    Codevs 1993 草地排水
    指针与引用
    江哥的DP题(G)
    江哥的DP题(F)
  • 原文地址:https://www.cnblogs.com/zhsl/p/2770048.html
Copyright © 2011-2022 走看看