Problem p00268 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <map>
#include <queue>
#include <utility>
#include <vector>

using namespace std;

struct Point {
  int x, y;
  int id;
  Point() {}
  Point(int a, int b, int c) : x(a), y(b), id(c) {}
};

Point points[110];
int pid[110];

bool cmp(const Point &p1, const Point &p2) {
  if (p1.x != p2.x)
    return p1.x < p2.x;
  return p1.y < p2.y;
}

int center;

bool cmp_angle(const int &id1, const int &id2) {
  int center = pid[::center];
  int id1_ = pid[id1], id2_ = pid[id2];
  int dx1 = points[id1_].x - points[center].x;
  int dy1 = points[id1_].y - points[center].y;
  int dx2 = points[id2_].x - points[center].x;
  int dy2 = points[id2_].y - points[center].y;
  //(-y,x)
  double ang1 = atan2(dx1, -dy1);
  double ang2 = atan2(dx2, -dy2);
  return ang1 < ang2;
}

vector<int> G[110];

vector<vector<int>> vs;
vector<int> dG[750];

typedef pair<int, int> P;

map<P, int> cnt;
queue<P> que;
int a;
void init() {
  vs.clear();
  for (int i = 0; i < 110; i++)
    G[i].clear();
  for (int i = 0; i < 550; i++)
    dG[i].clear();
  cnt.clear();
  a = 0;
}

vector<int> res;
void stroke(int u, int v, int st, int st2) {
  // u->v
  P p = P(min(u, v), max(u, v));
  if (cnt[p] == 0) {
    que.push(P(v, u));
  }
  cnt[p]++;
  //	if(v==st) return;
  if (u == st) {
    a++;
    res.push_back(u);
  }
  // res.push_back(v);
  a++;
  center = v;
  int id = distance(G[v].begin(),
                    lower_bound(G[v].begin(), G[v].end(), u, cmp_angle));
  if (id == G[v].size() - 1)
    id = 0;
  else
    id++;
  int nxt = G[v][id];
  if (v == st && nxt == st2)
    return;
  else {
    res.push_back(v);
  }
  stroke(v, nxt, st, st2);
}

void getGraph(int W) {
  int n = 0;
  int V = vs.size();
  for (int i = 0; i < V; i++)
    for (int j = i + 1; j < V; j++) {
      int ni = vs[i].size(), nj = vs[j].size();
      bool flg = false;
      for (int iid = 0; iid < ni; iid++)
        for (int jid = 0; jid < nj; jid++) {
          int niid = iid == ni - 1 ? 0 : iid + 1;
          int njid = jid == nj - 1 ? 0 : jid + 1;
          if (vs[i][iid] == vs[j][njid] && vs[i][niid] == vs[j][jid]) {
            flg = true;
            n++;
          }
        }
      if (flg) {
        dG[i].push_back(j);
        dG[j].push_back(i);
      }
    }
}

vector<int> outSide;

int getMostOutSide() {
  int u = points[0].id;
  int v = G[u][0];
  for (int i = 0; i < vs.size(); i++) {
    for (int j = 0; j + 1 < vs[i].size(); j++) {
      if (vs[i][j] == u && vs[i][j + 1] == v)
        return i;
    }
    if (vs[i][vs[i].size() - 1] == u && vs[i][0] == v)
      return i;
  }
  return -1;
}

int dis[750];
queue<int> bfs_que;
void bfs(int s) {
  while (!bfs_que.empty())
    bfs_que.pop();
  bfs_que.push(s);
  for (int i = 0; i < 750; i++)
    dis[i] = 1 << 29;
  dis[s] = 0;
  bfs_que.push(s);
  while (!bfs_que.empty()) {
    int v = bfs_que.front();
    bfs_que.pop();
    for (int i = 0; i < dG[v].size(); i++) {
      int u = dG[v][i];
      int nd = dis[v] + 1;
      if (nd >= dis[u])
        continue;
      dis[u] = nd;
      bfs_que.push(u);
    }
  }
}

int main() {
  while (true) {
    int C, W;
    scanf("%d%d", &C, &W);
    if (C == 0)
      break;
    init();
    for (int i = 0; i < C; i++) {
      int x, y;
      scanf("%d%d", &x, &y);
      points[i] = Point(x, y, i);
    }
    sort(points, points + C, cmp);
    for (int i = 0; i < C; i++)
      pid[points[i].id] = i;
    int su = -1, sv = -1;
    for (int i = 0; i < W; i++) {
      int u, v;
      scanf("%d%d", &u, &v);
      u--;
      v--;
      G[u].push_back(v);
      G[v].push_back(u);
      su = u, sv = v;
    }
    for (int i = 0; i < C; i++) {
      center = i;
      sort(G[i].begin(), G[i].end(), cmp_angle);
    }
    que.push(P(min(su, sv), max(su, sv)));
    while (!que.empty()) {
      P p = que.front();
      que.pop();
      int u = p.first, v = p.second;
      P pp = P(min(u, v), max(u, v));
      if (cnt[pp] == 2)
        continue;
      res.clear();
      stroke(u, v, u, v);
      vs.push_back(res);
    }
    if (a < 2 * W)
      for (;;)
        ;
    // if(cnt.size()<W) for(;;);
    getGraph(W);
    int out = getMostOutSide();
    bfs(out);
    int ans = 0;
    for (int i = 0; i < vs.size(); i++)
      ans = max(ans, dis[i]);
    printf("%d\\n", ans);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <map>
#include <queue>
#include <utility>
#include <vector>

using namespace std;

struct Point {
  int x, y;
  int id;
  Point() {}
  Point(int a, int b, int c) : x(a), y(b), id(c) {}
};

Point points[110];
int pid[110];

bool cmp(const Point &p1, const Point &p2) {
  if (p1.x != p2.x)
    return p1.x < p2.x;
  return p1.y < p2.y;
}

int center;

bool cmp_angle(const int &id1, const int &id2) {
  int center = pid[::center];
  int id1_ = pid[id1], id2_ = pid[id2];
  int dx1 = points[id1_].x - points[center].x;
  int dy1 = points[id1_].y - points[center].y;
  int dx2 = points[id2_].x - points[center].x;
  int dy2 = points[id2_].y - points[center].y;
  //(-y,x)
  double ang1 = atan2(dx1, -dy1);
  double ang2 = atan2(dx2, -dy2);
  return ang1 < ang2;
}

vector<int> G[110];

vector<vector<int>> vs;
vector<int> dG[750];

typedef pair<int, int> P;

map<P, int> cnt;
queue<P> que;
int a;
void init() {
  vs.clear();
  for (int i = 0; i < 110; i++)
    G[i].clear();
  for (int i = 0; i < 550; i++)
    dG[i].clear();
  cnt.clear();
  a = 0;
}

vector<int> res;
void stroke(int u, int v, int st) {
  // u->v
  P p = P(min(u, v), max(u, v));
  if (cnt[p] == 0) {
    que.push(P(v, u));
  }
  cnt[p]++;
  if (v == st)
    return;
  if (u == st) {
    a++;
    res.push_back(u);
  }
  res.push_back(v);
  a++;
  center = v;
  int id = distance(G[v].begin(),
                    lower_bound(G[v].begin(), G[v].end(), u, cmp_angle));
  if (id == G[v].size() - 1)
    id = 0;
  else
    id++;
  int nxt = G[v][id];
  stroke(v, nxt, st);
}

void getGraph(int W) {
  int n = 0;
  int V = vs.size();
  for (int i = 0; i < V; i++)
    for (int j = i + 1; j < V; j++) {
      int ni = vs[i].size(), nj = vs[j].size();
      bool flg = false;
      for (int iid = 0; iid < ni; iid++)
        for (int jid = 0; jid < nj; jid++) {
          int niid = iid == ni - 1 ? 0 : iid + 1;
          int njid = jid == nj - 1 ? 0 : jid + 1;
          if (vs[i][iid] == vs[j][njid] && vs[i][niid] == vs[j][jid]) {
            flg = true;
            n++;
          }
        }
      if (flg) {
        dG[i].push_back(j);
        dG[j].push_back(i);
      }
    }
}

vector<int> outSide;

int getMostOutSide() {
  int u = points[0].id;
  int v = G[u][0];
  for (int i = 0; i < vs.size(); i++) {
    for (int j = 0; j + 1 < vs[i].size(); j++) {
      if (vs[i][j] == u && vs[i][j + 1] == v)
        return i;
    }
    if (vs[i][vs[i].size() - 1] == u && vs[i][0] == v)
      return i;
  }
  return -1;
}

int dis[750];
queue<int> bfs_que;
void bfs(int s) {
  while (!bfs_que.empty())
    bfs_que.pop();
  bfs_que.push(s);
  for (int i = 0; i < 750; i++)
    dis[i] = 1 << 29;
  dis[s] = 0;
  bfs_que.push(s);
  while (!bfs_que.empty()) {
    int v = bfs_que.front();
    bfs_que.pop();
    for (int i = 0; i < dG[v].size(); i++) {
      int u = dG[v][i];
      int nd = dis[v] + 1;
      if (nd >= dis[u])
        continue;
      dis[u] = nd;
      bfs_que.push(u);
    }
  }
}

int main() {
  while (true) {
    int C, W;
    scanf("%d%d", &C, &W);
    if (C == 0)
      break;
    init();
    for (int i = 0; i < C; i++) {
      int x, y;
      scanf("%d%d", &x, &y);
      points[i] = Point(x, y, i);
    }
    sort(points, points + C, cmp);
    for (int i = 0; i < C; i++)
      pid[points[i].id] = i;
    int su = -1, sv = -1;
    for (int i = 0; i < W; i++) {
      int u, v;
      scanf("%d%d", &u, &v);
      u--;
      v--;
      G[u].push_back(v);
      G[v].push_back(u);
      su = u, sv = v;
    }
    for (int i = 0; i < C; i++) {
      center = i;
      sort(G[i].begin(), G[i].end(), cmp_angle);
    }
    que.push(P(min(su, sv), max(su, sv)));
    while (!que.empty()) {
      P p = que.front();
      que.pop();
      int u = p.first, v = p.second;
      P pp = P(min(u, v), max(u, v));
      if (cnt[pp] == 2)
        continue;
      res.clear();
      stroke(u, v, u);
      vs.push_back(res);
    }
    if (a < 2 * W)
      for (;;)
        ;
    // if(cnt.size()<W) for(;;);
    getGraph(W);
    int out = getMostOutSide();
    bfs(out);
    int ans = 0;
    for (int i = 0; i < vs.size(); i++)
      ans = max(ans, dis[i]);
    printf("%d\\n", ans);
  }
  return 0;
}