zoukankan      html  css  js  c++  java
  • POJ 2446 Chessboard (二分匹配)

     1 #include<stdio.h>
     2 #include<math.h>
     3 #include<string.h>
     4 #define maxn 1050//表示x集合和y集合中顶点的最大个数
     5 int nx,ny;//x集合和y集合中顶点的个数
     6 int edge[maxn][maxn];//edge[i][j]为1表示ij可以匹配
     7 int cx[maxn],cy[maxn];//用来记录x集合中匹配的y元素是哪个
     8 int visited[maxn];//用来记录该顶点是否被访问过
     9 int path(int u)
    10 {
    11     int v;
    12     for(v=0;v<=ny;v++)
    13      {
    14          if(edge[u][v]&&!visited[v])
    15         {
    16            visited[v]=1;
    17             if(cy[v]==-1||path(cy[v]))//如果y集合中的v元素没有匹配或者是v已经匹配,但是从cy[v]中能够找到一条增广路
    18             {
    19                 cx[u]=v;//这是无向图中才要的
    20                 cy[v]=u;
    21                 return 1;
    22             }
    23         }
    24     }
    25     return 0;
    26 }
    27 int maxmatch()
    28 {
    29     int res=0,i;
    30     for(i=0;i<maxn;i++)
    31        cx[i]=cy[i]=-1;//初始值为-1表示两个集合中都没有匹配的元素!
    32     for(i=0;i<=nx;i++)
    33     {
    34         if(cx[i]==-1)
    35         {
    36             memset(visited,0,sizeof(visited));
    37             res+=path(i);
    38         }
    39     }
    40     return res;
    41  }
    42 int main()
    43 {
    44     int i,j,x,y,ans,n,m,k,s;
    45     while(scanf("%d%d%d",&n,&m,&k)!=EOF)
    46     {
    47         ny=nx=n*m;
    48         memset(edge,0,sizeof(edge));
    49         s=1;
    50         for(i=1;i<=n;i++)
    51             for(j=1;j<=m;j++)
    52             {
    53                 if(i>1)edge[s-m][s]=1;
    54                 if(i<n)edge[s+m][s]=1;
    55                 if(j>1)edge[s][s-1]=1;
    56                 if(j<m)edge[s][s+1]=1;
    57                 s++;
    58             }
    59         for(i=0;i<k;i++)
    60             {
    61                 scanf("%d%d",&y,&x);
    62                 s=(x-1)*m+y;
    63                 //printf("s=%d
    ",s);
    64                 if(x>1)edge[s-m][s]=edge[s][s-m]=0;
    65                 if(x<n)edge[s+m][s]=edge[s][s+m]=0;
    66                 if(y>1)edge[s][s-1]=edge[s-1][s]=0;
    67                 if(y<m)edge[s][s+1]=edge[s+1][s]=0;
    68             }
    69         /*for(i=1;i<=m*n;i++)
    70             for(j=1;j<=m*n;j++)
    71             {
    72                 if(edge[i][j])
    73                 printf("i=%d,j=%d,edge==%d
    ",i,j,edge[i][j]);
    74             }*/
    75         /*for(i=0;i<nx;i++)
    76             for(j=0;j<ny;j++)
    77            if(edge[i][j])printf("%d-->%d
    ",i,j);*/
    78         ans=maxmatch();
    79         if(ans==m*n-k)printf("YES
    ");
    80         else printf("NO
    ");
    81         //printf("%d
    ",ans);
    82     }
    83     return 0;
    84 }
    View Code

    给图中每个格子编号,然后将之放入二分匹配中的两个集合里面,再将能连接即能覆盖的两个点连接起来。接下来就是模板的力量了。。。。赶脚这个构图法会是最猥琐的没有之一。

    http://poj.org/problem?id=2446

  • 相关阅读:
    分享一个新软件 云端软件平台+个人使用心得
    扩展easyui.datagrid,添加数据loading遮罩
    在Flash中结合webservice 实现无缝滚动效果
    使用HttpWebRequest访问Web服务,并传递Cookie数据
    批量生成一组不同随机字符串
    文章分享代码
    jQuery.easyui与jQuery UI冲突
    转换BBSXP 2008到Discuz X1.5部分问题解决记录
    在ASP.NET的server form 中使用easyui的layout布局控件
    神奇3D圣诞树高超的技术!
  • 原文地址:https://www.cnblogs.com/huzhenbo113/p/3687316.html
Copyright © 2011-2022 走看看