Problem p00454 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <utility>
#include <vector>
using namespace std;
int n;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
// vector<int> xl, yl, xr, yr;

// 座標は 2n+2 個ある
void coordinate_compress(vector<int> &xl, vector<int> &xr, int &t) {
  vector<int> xc(2 * n + 2);
  for (int i = 0; i < n; i++) {
    xc[i] = xl[i];
    xc[i + n] = xr[i];
  }
  xc[2 * n] = 0;
  xc[2 * n + 1] = t;

  sort(xc.begin(), xc.end());
  // 重複を削除
  xc.erase(unique(xc.begin(), xc.end()), xc.end());

  map<int, int> zip;
  for (int i = 0; i < xc.size(); i++) {
    zip[xc[i]] = i;
  }

  for (int i = 0; i < n; i++) {
    xl[i] = zip[xl[i]];
    xr[i] = zip[xr[i]];
  }
  t = zip.size() - 1;
}

int main() {
  ifstream cin("../test.txt");
  while (true) {
    int w, h;
    cin >> w >> h >> n;

    if (!(w | h))
      break;

    vector<int> xl, yl, xr, yr;
    xl = vector<int>(n);
    xr = vector<int>(n);
    yl = vector<int>(n);
    yr = vector<int>(n);
    for (int i = 0; i < n; i++) {
      cin >> xl[i] >> yl[i] >> xr[i] >> yr[i];
    }

    // 座標圧縮
    coordinate_compress(xl, xr, w);
    coordinate_compress(yl, yr, h);

    // 10 10
    // 2
    // 5 0 6 10
    // 0 5 10 8
    // ->
    // 3 3
    // 1 0 2 3
    // 1 1 3 2 <- これが実行するたびに違う 0 1 1 0 も。

    // 表示　テープの座標
    // for (int i = 0; i < n; i++) {
    //   cout << w << " " << h << endl;
    //   cout << xl[i] << " " << yl[i] << " " << xr[i] << " " << yr[i] << endl;
    // }

    // テープを貼る
    // 格子は左下の座標を基準にする
    vector<vector<int>> m(w, vector<int>(h + 1));
    for (int i = 0; i < w; i++) {
      for (int j = 0; j <= h; j++) {
        m[i][j] = 0;
      }
    }
    for (int i = 0; i < n; i++) {
      for (int x = xl[i]; x < xr[i]; x++) {
        m[x][yl[i]] += 1;
        m[x][yr[i]] -= 1;
        if (xl[i] >= w || xr[i] > w || yl[i] >= h || yr[i] > h)
          cout << "warning" << endl;
      }
    }

    for (int y = 1; y < h; y++) {
      for (int x = 0; x < w; x++) {
        m[x][y] += m[x][y - 1];
      }
    }

    // 表示
    // for (int y = h-1; y >= 0; y--) {
    //   for (int x = 0; x < w; x++) {
    //     if (m[x][y] == 0) {
    //       cout << ".";
    //     } else {
    //       cout << "*";
    //     }
    //   }
    //   cout << endl;
    // }

    // 色を幅優先で塗る
    int cnt_clr = 0;
    queue<pair<int, int>> qu;
    for (int x = 0; x < w; x++) {
      for (int y = 0; y < h; y++) {
        if (m[x][y] <= 0) { // テープがなければ色塗り開始
          cnt_clr++;
          qu.push(make_pair(x, y));
          while (!qu.empty()) {
            pair<int, int> p = qu.front();
            qu.pop();
            for (int i = 0; i < 4; i++) {
              int nx = p.first + dx[i];
              int ny = p.second + dy[i];
              if (nx >= 0 && nx < w && ny >= 0 && ny < h && m[nx][ny] <= 0) {
                m[nx][ny] = 1;
                qu.push(make_pair(nx, ny));
              }
            }
          }
        }
      }
    }

    // 出力
    cout << cnt_clr << endl;
  }
}

Fixed submission:
#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <utility>
#include <vector>
using namespace std;
int n;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
// vector<int> xl, yl, xr, yr;

// 座標は 2n+2 個ある
void coordinate_compress(vector<int> &xl, vector<int> &xr, int &t) {
  vector<int> xc(2 * n + 2);
  for (int i = 0; i < n; i++) {
    xc[i] = xl[i];
    xc[i + n] = xr[i];
  }
  xc[2 * n] = 0;
  xc[2 * n + 1] = t;

  sort(xc.begin(), xc.end());
  // 重複を削除
  xc.erase(unique(xc.begin(), xc.end()), xc.end());

  map<int, int> zip;
  for (int i = 0; i < xc.size(); i++) {
    zip[xc[i]] = i;
  }

  for (int i = 0; i < n; i++) {
    xl[i] = zip[xl[i]];
    xr[i] = zip[xr[i]];
  }
  t = zip.size() - 1;
}

int main() {
  // ifstream cin("../test.txt");
  while (true) {
    int w, h;
    cin >> w >> h >> n;

    if (!(w | h))
      break;

    vector<int> xl, yl, xr, yr;
    xl = vector<int>(n);
    xr = vector<int>(n);
    yl = vector<int>(n);
    yr = vector<int>(n);
    for (int i = 0; i < n; i++) {
      cin >> xl[i] >> yl[i] >> xr[i] >> yr[i];
    }

    // 座標圧縮
    coordinate_compress(xl, xr, w);
    coordinate_compress(yl, yr, h);

    // 10 10
    // 2
    // 5 0 6 10
    // 0 5 10 8
    // ->
    // 3 3
    // 1 0 2 3
    // 1 1 3 2 <- これが実行するたびに違う 0 1 1 0 も。

    // 表示　テープの座標
    // for (int i = 0; i < n; i++) {
    //   cout << w << " " << h << endl;
    //   cout << xl[i] << " " << yl[i] << " " << xr[i] << " " << yr[i] << endl;
    // }

    // テープを貼る
    // 格子は左下の座標を基準にする
    vector<vector<int>> m(w, vector<int>(h + 1));
    for (int i = 0; i < w; i++) {
      for (int j = 0; j <= h; j++) {
        m[i][j] = 0;
      }
    }
    for (int i = 0; i < n; i++) {
      for (int x = xl[i]; x < xr[i]; x++) {
        m[x][yl[i]] += 1;
        m[x][yr[i]] -= 1;
        if (xl[i] >= w || xr[i] > w || yl[i] >= h || yr[i] > h)
          cout << "warning" << endl;
      }
    }

    for (int y = 1; y < h; y++) {
      for (int x = 0; x < w; x++) {
        m[x][y] += m[x][y - 1];
      }
    }

    // 表示
    // for (int y = h-1; y >= 0; y--) {
    //   for (int x = 0; x < w; x++) {
    //     if (m[x][y] == 0) {
    //       cout << ".";
    //     } else {
    //       cout << "*";
    //     }
    //   }
    //   cout << endl;
    // }

    // 色を幅優先で塗る
    int cnt_clr = 0;
    queue<pair<int, int>> qu;
    for (int x = 0; x < w; x++) {
      for (int y = 0; y < h; y++) {
        if (m[x][y] <= 0) { // テープがなければ色塗り開始
          cnt_clr++;
          qu.push(make_pair(x, y));
          while (!qu.empty()) {
            pair<int, int> p = qu.front();
            qu.pop();
            for (int i = 0; i < 4; i++) {
              int nx = p.first + dx[i];
              int ny = p.second + dy[i];
              if (nx >= 0 && nx < w && ny >= 0 && ny < h && m[nx][ny] <= 0) {
                m[nx][ny] = 1;
                qu.push(make_pair(nx, ny));
              }
            }
          }
        }
      }
    }

    // 出力
    cout << cnt_clr << endl;
  }
}