Advertisement
Mihai_Preda

Untitled

Jan 15th, 2021
246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.48 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4.  
  5. using namespace std;
  6.  
  7. class bipart
  8. {
  9. public:
  10.     bipart(int n, int m)
  11.     {
  12.         this->n = n;
  13.         this->m = m;
  14.         edges.resize(n + 1);
  15.     }
  16.     void AddEdge(int x, int y)
  17.     {
  18.         edges[x].push_back(y);
  19.     }
  20.     void GetCuplaj(vector<pair<int, int> > &ret)
  21.     {
  22.         vector<int> to(n+1), from(m+1);
  23.         vector<bool> viz(n+1);
  24.         bool cuplat = true;
  25.         while(cuplat)
  26.         {
  27.             cuplat = false;
  28.             fill(viz.begin(), viz.end(), false);
  29.             for(int i = 1; i <= n; ++i)
  30.                 if(to[i] == 0 && cupleaza(i, viz, to, from))
  31.                     cuplat = true;
  32.         }
  33.         for(int i = 1; i <= n; ++i)
  34.             if(to[i] != 0)
  35.                 ret.push_back({i, to[i]});
  36.     }
  37. private:
  38.     bool cupleaza(int nod, vector<bool> &viz, vector<int> &to, vector<int> &from)
  39.     {
  40.         if(viz[nod])
  41.             return false;
  42.         viz[nod] = true;
  43.         for(auto v:edges[nod])
  44.             if(from[v] == 0)
  45.             {
  46.                to[nod] = v;
  47.                from[v] = nod;
  48.                return true;
  49.             }
  50.         for(auto v:edges[nod])
  51.             if(cupleaza(from[v], viz, to, from))
  52.             {
  53.                 to[nod] = v;
  54.                 from[v] = nod;
  55.                 return true;
  56.             }
  57.         return false;
  58.     }
  59.     vector<vector<int> > edges;
  60.     int n, m;
  61. };
  62.  
  63. int n, m;
  64. char a[205][205];
  65.  
  66. inline bool isLeftBlack(int i, int j)
  67. {
  68.     if(j == 1 || a[i][j-1] == '.')
  69.         return false;
  70.     return true;
  71. }
  72.  
  73. inline bool isRightBlack(int i, int j)
  74. {
  75.     if(j == m || a[i][j+1] == '.')
  76.         return false;
  77.     return true;
  78. }
  79.  
  80. inline bool isUpBlack(int i, int j)
  81. {
  82.     if(i == 1 || a[i-1][j] == '.')
  83.         return false;
  84.     return true;
  85. }
  86.  
  87. inline bool isDownBlack(int i, int j)
  88. {
  89.     if(i == n || a[i+1][j] == '.')
  90.         return false;
  91.     return true;
  92. }
  93.  
  94. inline int getIndRow(int i, int j)
  95. {
  96.     return (i-1) * m + j;
  97. }
  98.  
  99. inline int getIndCol(int i, int j)
  100. {
  101.     return (i-1) * (m-1) + j;
  102. }
  103.  
  104. int main()
  105. {
  106.     cin >> n >> m;
  107.     bipart graf((n-1) * m, n * (m-1));
  108.     for(int i = 1; i <= n; ++i)
  109.         cin >> (a[i]+1);
  110.     int rasp = 0;
  111.     // rasp = nr_negre - MIS = nr_negre - (noduri - cuplaj) = nr_negre - noduri + cuplaj
  112.     for(int i = 1; i <= n; ++i)
  113.         for(int j = 1; j <= m; ++j)
  114.         {
  115.             if(a[i][j] == '#')
  116.             {
  117.                 rasp++; // patratica neagra
  118.                 if(isLeftBlack(i, j))
  119.                     rasp--; // pentru fiecare patratel numaram nodul din stanga
  120.                 if(isUpBlack(i, j))
  121.                 {
  122.                     rasp--; // pentru fiecare patratel numaram nodul de sus
  123.                     if(isLeftBlack(i, j))
  124.                         graf.AddEdge(getIndRow(i-1, j), getIndCol(i, j-1));
  125.                     if(isRightBlack(i, j))
  126.                         graf.AddEdge(getIndRow(i-1, j), getIndCol(i, j));
  127.                 }
  128.                 if(isDownBlack(i, j))
  129.                 {
  130.                     if(isLeftBlack(i, j))
  131.                         graf.AddEdge(getIndRow(i, j), getIndCol(i, j-1));
  132.                     if(isRightBlack(i, j))
  133.                         graf.AddEdge(getIndRow(i, j), getIndCol(i, j));
  134.                 }
  135.             }
  136.         }
  137.  
  138.     vector<pair<int, int> > cuplaj;
  139.     graf.GetCuplaj(cuplaj);
  140.  
  141.     cout << rasp + (int)cuplaj.size();
  142.     return 0;
  143. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement