• 【最小路径覆盖】BZOJ2150-部落战争


    【题目大意】

    给出一张图,'*'表示不能走的障碍。已知每只军队可以按照r*c的方向行军,且军队与军队之间路径不能交叉。问占据全部'.'最少要多少支军队?

    【思路】

    首先注意题意中有说“军队只能往下走”,弄清楚方向。

    从某点往它能走的四个点走一趟,连边。最小路径覆盖=总数-二分图最大匹配。

    哦耶!老了,连匈牙利的板子都敲错orzzzzzz

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MAXN=55;
     4 int m,n,r,c,maps[MAXN][MAXN];
     5 int lk[MAXN*MAXN],vis[MAXN*MAXN];
     6 vector<int> E[MAXN*MAXN];
     7 
     8 int check(int x,int y)
     9 {
    10     if (x>=1 && x<=m && y>=1 && y<=n && maps[x][y]) return 1;else return 0;
    11 }
    12 
    13 int id(int x,int y){return ((x-1)*n+y);}
    14 
    15 void addedge(int u,int v)
    16 {
    17     E[u].push_back(v);
    18 }
    19 
    20 int find(int u)
    21 {
    22     for (int i=E[u].size()-1;i>=0;i--)
    23     {
    24         int v=E[u][i];
    25         if (!vis[v])
    26         {
    27             vis[v]=1;
    28             if (!lk[v]|| find(lk[v]))//呜哇这里写成了find(v)半天没有发现,果然是老阿姨了啊 
    29             {
    30                 lk[v]=u;
    31                 return 1;
    32             }
    33         }
    34     }
    35     return 0;
    36 }
    37 
    38 void init()
    39 {
    40     scanf("%d%d%d%d",&m,&n,&r,&c);
    41     for (int i=1;i<=m;i++)
    42     {
    43         char str[MAXN];
    44         scanf("%s",str);
    45         for (int j=0;j<n;j++)
    46             if (str[j]=='.') maps[i][j+1]=1;else maps[i][j+1]=0;
    47     }
    48     for (int i=1;i<=m;i++)
    49         for (int j=1;j<=n;j++)
    50             if (maps[i][j])
    51             {
    52                 if (check(i+r,j+c)) addedge(id(i,j),id(i+r,j+c));
    53                 if (check(i+r,j-c)) addedge(id(i,j),id(i+r,j-c));
    54                 if (check(i+c,j+r))    addedge(id(i,j),id(i+c,j+r));
    55                 if (check(i+c,j-r)) addedge(id(i,j),id(i+c,j-r));
    56             }
    57 }
    58 
    59 void solve()
    60 {
    61     memset(lk,0,sizeof(lk));
    62     int sum=0,ans=0;
    63     for (int i=1;i<=m;i++)
    64         for (int j=1;j<=n;j++)
    65         {
    66             if (maps[i][j]==1)
    67             {
    68                 int x=id(i,j);
    69                 memset(vis,0,sizeof(vis));
    70                 sum++;
    71                 if (find(x)) ans++;
    72             }
    73         }
    74     printf("%d",sum-ans);
    75 }
    76 
    77 int main()
    78 {
    79     init();
    80     solve();
    81 }
  • 相关阅读:
    Windows下python3安装pip管理包(转贴)
    AnyConnect removes "Connections" tab from IE Settings solution
    split陷阱
    java不足前面补0
    linux定时任务cron配置说明
    maven常用的plugin
    linux部署两个tomcat
    spring定时任务配置,以及不执行的解决办法
    windows10 自带笔记本键盘禁止和开启
    spring task的定时任务突然断了
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5928270.html
Copyright © 2020-2023  润新知