• poj2226Muddy Fields(二分图的最小点覆盖)


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

    模板抄错,结果错了一下午。将连续横行上的*和连续纵桁上点分别看做两个点集,连接两集合中点的边就是图中的点。即求最小顶点覆盖最多的边。最小点覆盖=最大匹配。

    有篇图片的讲解,挺好,很形象。http://ip96cns.blog.163.com/blog/static/170095192201117465473/

    View Code
     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 int map[1000][1000];
     6 int r,c,link[1000],vis[1000];
     7 int find(int x,int n)//二分匹配模板
     8 {
     9     int i,j;
    10     for(i = 1; i <= n ; i++)
    11     {
    12         if(map[x][i]&&!vis[i])
    13         {
    14             vis[i] = 1;
    15             if(link[i]==0||find(link[i],n))
    16             {
    17                 link[i] = x;
    18                 return 1;
    19             }
    20         }
    21     }
    22     return 0;
    23 }
    24 int main()
    25 {
    26     int i,j,k,a[100][100],b[100][100];
    27     char s[100][100];
    28     while(cin>>r>>c)
    29     {
    30         memset(link,0,sizeof(link));
    31 
    32         memset(map,0,sizeof(map));
    33         k = 0;
    34         int sum = 0;
    35         int ii=1,jj=1;
    36         for(i = 1 ; i <= r ; i++)
    37         {
    38             getchar();
    39             for(j = 1; j <= c ; j++)
    40             {
    41                 scanf("%c", &s[i][j]);
    42             }
    43         }
    44         for(i = 1; i <= r ; i++)
    45         for(j = 1; j <= c ; j++)//建立X集合中的点
    46         {
    47             if(j==1&&i!=1&&s[i-1][c]=='*')
    48             ii++;
    49             if(s[i][j]=='*')
    50             {
    51                 a[i][j] = ii;
    52             }
    53             if(j!=c&&(s[i][j]=='*'&&s[i][j+1]!='*'))
    54                 ii++;
    55         }
    56         for(i = 1; i <= c ; i++)//建立Y集合中的点
    57         for(j = 1; j <= r ; j++)
    58         {
    59             if((j==1&&i!=1&&s[r][i-1]=='*'))
    60             jj++;
    61             if(s[j][i]=='*')
    62             b[j][i] = jj;
    63             if(j!=r&&(s[j][i]=='*'&&s[j+1][i]!='*'))
    64             {
    65                 jj++;
    66             }
    67         }
    68         for(i = 1; i <= r ; i++)
    69         for(j = 1; j <= c ; j++)//建立连接两集合点的边,即图中的"*"
    70         {
    71             if(s[i][j]=='*')
    72             {
    73                 map[a[i][j]][b[i][j]] = 1;
    74             }
    75         }
    76         for(i = 1; i <= ii ; i++)
    77         {
    78             memset(vis,0,sizeof(vis));
    79             if(find(i,jj))//寻找最大匹配
    80             {
    81                 sum++;
    82             }
    83         }
    84         cout<<sum<<endl;
    85     }
    86     return 0;
    87 }
  • 相关阅读:
    顺时针
    true
    td
    确定删除
    on("submit",)
    float:right
    css中:hover空格
    磁盘恢复
    一、报表
    二、实践与视频解决方案
  • 原文地址:https://www.cnblogs.com/shangyu/p/2866673.html
Copyright © 2020-2023  润新知