zoukankan      html  css  js  c++  java
  • pku3020 Antenna Placement (解法1)

    题解:在一个n*m的棋盘上,有一些标志,问最少用多少个1*2的矩形可以把它们全部套住。 
    可以将每一个标志与其相邻的四个标志建一条边,这样就形成了一个无向图,题目的意思即要求最小的边数。使得所有的点都在这些边数。
    这样就转换成了最小路径覆盖问题。
    最小路径覆盖=顶点数-最大二分匹配
    本题是无向图,即二分图中的边是双向边,若1和2匹配的话,那么2和1也匹配,
    所以本题=顶点数-最大二分匹配/2
     1 #include<iostream>
    2 using namespace std;
    3 const int Row=45;
    4 const int Line=15;
    5 char str[Row][Line];
    6 bool cover[Row][Line];
    7 char dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1} ;
    8 int h,w,cnt;
    9 struct Link
    10 {
    11 int x,y;
    12 }link[Row][Line];
    13 bool find (int py, int px)
    14 {
    15 int i, j ;
    16 int x, y ;
    17 for (i = 0 ; i < 4 ; ++i)
    18 {
    19 y = py + dir[i][0] ;
    20 x = px + dir[i][1] ;
    21 if ((0<x && x <=w && 0<y && y<=h) && !cover[y][x] && (str[y][x]=='*'))
    22 {
    23 cover[y][x] = true ;
    24 if (!link[y][x].x || find (link[y][x].y, link[y][x].x))
    25 {
    26 link[y][x].y = py ;
    27 link[y][x].x = px ;
    28 return 1 ;
    29 }
    30 }
    31 }
    32 return 0 ;
    33 }
    34
    35
    36
    37 int mach()
    38 {
    39 int sum=0;
    40 for (int j = 1 ; j <=h ; ++j)
    41 for (int i = 1 ; i <=w ; ++i)
    42 {
    43 if (str[j][i] == '*')
    44 {
    45 ++cnt ;
    46 memset (cover, false, sizeof (cover)) ;
    47 sum += find (j, i) ;
    48 }
    49 }
    50 return cnt-sum/2;
    51 }
    52
    53 int main()
    54 {
    55 int k;
    56 scanf("%d",&k);
    57
    58 while(k--)
    59 {
    60 cnt=0;
    61 scanf("%d %d",&h,&w);
    62 memset(link,0,sizeof(link));
    63 for(int i=1;i<=h;i++)
    64 {
    65 scanf("%s",&str[i][1]);
    66 }
    67 printf("%d\n",mach());
    68 }
    69
    70 return 0;
    71 }


     1 #include<iostream>
    2 using namespace std;
    3 const int Row=45;
    4 const int Line=15;
    5 char str[Row][Line];
    6 bool cover[Row][Line];
    7 char dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1} ;
    8 int h,w,cnt;
    9 struct Link
    10 {
    11 int x,y;
    12 }link[Row][Line];
    13 bool find (int py, int px)
    14 {
    15 int i, j ;
    16 int x, y ;
    17 for (i = 0 ; i < 4 ; ++i)
    18 {
    19 y = py + dir[i][0] ;
    20 x = px + dir[i][1] ;
    21 if ((0<x && x <=w && 0<y && y<=h) && !cover[y][x] && (str[y][x]=='*'))
    22 {
    23 cover[y][x] = true ;
    24 if (!link[y][x].x || find (link[y][x].y, link[y][x].x))
    25 {
    26 link[y][x].y = py ;
    27 link[y][x].x = px ;
    28 return 1 ;
    29 }
    30 }
    31 }
    32 return 0 ;
    33 }
    34
    35
    36
    37 int mach()
    38 {
    39 int sum=0;
    40 for (int j = 1 ; j <=h ; ++j)
    41 for (int i = 1 ; i <=w ; ++i)
    42 {
    43 if (str[j][i] == '*')
    44 {
    45 ++cnt ;
    46 memset (cover, false, sizeof (cover)) ;
    47 sum += find (j, i) ;
    48 }
    49 }
    50 return cnt-sum/2;
    51 }
    52
    53 int main()
    54 {
    55 int k;
    56 scanf("%d",&k);
    57
    58 while(k--)
    59 {
    60 cnt=0;
    61 scanf("%d %d",&h,&w);
    62 memset(link,0,sizeof(link));
    63 for(int i=1;i<=h;i++)
    64 {
    65 scanf("%s",&str[i][1]);
    66 }
    67 printf("%d\n",mach());
    68 }
    69
    70 return 0;
    71 }
     
    第二种解法将在近期公布。
  • 相关阅读:
    搞定 Linux Shell 文本处理工具,看完这篇还不够~
    ARM 版的Clang的使用
    GDB入门学习之gef插件的使用
    mac使用apktool
    python实现md5
    fridahookjava
    js hook array对象的push方法
    app逆向java转python代码
    python合并两个有序数组
    MySQL update 语句加锁分析
  • 原文地址:https://www.cnblogs.com/tiankonguse/p/2403068.html
Copyright © 2011-2022 走看看