Problem p04010 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define rep(i, a, b) for (int i = (a), _ = (b); i <= _; ++i)
#define per(i, a, b) for (int i = (a), _ = (b); i >= _; --i)
#define For(i, a, b) for (int i = (a), _ = (b); i < _; ++i)
#define fore(e, u, v) for (int p = e(u), v = e[p].y; p; v = e[p = e[p].nxt].y)
#define ri rd<int>
using namespace std;
const int maxN = 1e5 + 7;

template <class T> inline T rd() {
  bool f = 1;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-')
      f = 0;
  T x = 0;
  for (; isdigit(c); c = getchar())
    x = x * 10 + c - 48;
  return f ? x : -x;
}

inline void NIE() {
  puts("-1");
  exit(0);
}

int n, m, res;
int U, V, Kd;
int dep[maxN], sz[maxN], cnt[2];
bool vis[maxN];
int q[maxN], tt;

struct Vec {
  static const int maxE = maxN;
  int g[maxN], te;
  struct edge {
    int y, nxt;
  } e[maxE << 1];
  inline void push(int x, int y) {
    e[++te] = (edge){y, g[x]};
    g[x] = te;
  }
  inline void link(int x, int y) { push(x, y), push(y, x); }
  inline int &operator()(int x) { return g[x]; }
  inline edge &operator[](int x) { return e[x]; }
} e;

struct Rec {
  int x, c;
  inline void operator+=(const Rec &v) { x += v.x, c += v.c; }
} a[maxN];

void calc(Rec v) {
  if (v.x == 0)
    res += abs(v.c);
  else
    q[++tt] = -v.x * v.c;
}

int calcdis() {
  q[++tt] = 0;
  sort(q + 1, q + tt + 1);
  int p = tt >> 1, res = 0;
  rep(i, 1, tt) res += abs(q[p] - q[i]);
  return res;
}

void dfs(int x, int fa) {
  vis[x] = 1;
  ++cnt[dep[x] & 1];
  a[x] = (Rec){0, (dep[x] & 1) ? 1 : -1};
  fore(e, x, y) if (y != fa) {
    if (vis[y]) {
      U = y, V = x, Kd = (dep[U] & 1) == (dep[V] & 1);
    } else {
      dep[y] = dep[x] + 1;
      dfs(y, x);
    }
  }
}

void gao(int x, int fa) {
  vis[x] = 1;
  fore(e, x, y) if (y != fa && !vis[y]) {
    gao(y, x);
    a[x] += a[y];
  }
  if (x != 1)
    calc(a[x]);
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("a.in", "r", stdin);
#endif

  n = ri(), m = ri();
  rep(i, 1, m) e.link(ri(), ri());

  memset(vis, 0, sizeof vis);
  dfs(1, 0);

  if (((!U && !V) || Kd == 0) && cnt[0] != cnt[1])
    NIE();
  if ((Kd == 1) && (cnt[0] & 1) != (cnt[1] & 1))
    NIE();

  if (Kd == 1) { // odd
    int del = (cnt[0] - cnt[1]) >> 1;
    a[U].c += del, a[V].c += del, res += abs(del);
  } else if (U) { // even
    a[U].x = -1;
    a[V].x = 1;
  }

  memset(vis, 0, sizeof vis);
  gao(1, 0);

  printf("%d\n", res + calcdis());

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define rep(i, a, b) for (int i = (a), _ = (b); i <= _; ++i)
#define per(i, a, b) for (int i = (a), _ = (b); i >= _; --i)
#define For(i, a, b) for (int i = (a), _ = (b); i < _; ++i)
#define fore(e, u, v) for (int p = e(u), v = e[p].y; p; v = e[p = e[p].nxt].y)
#define ri rd<int>
using namespace std;
const int maxN = 1e5 + 7;

template <class T> inline T rd() {
  bool f = 1;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-')
      f = 0;
  T x = 0;
  for (; isdigit(c); c = getchar())
    x = x * 10 + c - 48;
  return f ? x : -x;
}

inline void NIE() {
  puts("-1");
  exit(0);
}

int n, m, res;
int U, V, Kd;
int dep[maxN], sz[maxN], cnt[2];
bool vis[maxN];
int q[maxN], tt;

struct Vec {
  static const int maxE = maxN;
  int g[maxN], te;
  struct edge {
    int y, nxt;
  } e[maxE << 1];
  inline void push(int x, int y) {
    e[++te] = (edge){y, g[x]};
    g[x] = te;
  }
  inline void link(int x, int y) { push(x, y), push(y, x); }
  inline int &operator()(int x) { return g[x]; }
  inline edge &operator[](int x) { return e[x]; }
} e;

struct Rec {
  int x, c;
  inline void operator+=(const Rec &v) { x += v.x, c += v.c; }
} a[maxN];

void calc(Rec v) {
  if (v.x == 0)
    res += abs(v.c);
  else
    q[++tt] = -v.x * v.c;
}

int calcdis() {
  q[++tt] = 0;
  sort(q + 1, q + tt + 1);
  int p = tt >> 1, res = 0;
  rep(i, 1, tt) res += abs(q[p] - q[i]);
  return res;
}

void dfs(int x, int fa) {
  vis[x] = 1;
  ++cnt[dep[x] & 1];
  a[x] = (Rec){0, (dep[x] & 1) ? 1 : -1};
  fore(e, x, y) if (y != fa) {
    if (vis[y]) {
      U = y, V = x, Kd = (dep[U] & 1) == (dep[V] & 1);
    } else {
      dep[y] = dep[x] + 1;
      dfs(y, x);
    }
  }
}

void gao(int x, int fa) {
  vis[x] = 1;
  fore(e, x, y) if (y != fa && !vis[y]) {
    gao(y, x);
    a[x] += a[y];
  }
  if (x != 1)
    calc(a[x]);
}

int main() {

  n = ri(), m = ri();
  rep(i, 1, m) e.link(ri(), ri());

  memset(vis, 0, sizeof vis);
  dfs(1, 0);

  if (((!U && !V) || Kd == 0) && cnt[0] != cnt[1])
    NIE();
  if ((Kd == 1) && (cnt[0] & 1) != (cnt[1] & 1))
    NIE();

  if (Kd == 1) { // odd
    int del = (cnt[0] - cnt[1]) >> 1;
    a[U].c += del, a[V].c += del, res += abs(del);
  } else if (U) { // even
    a[U].x = -1;
    a[V].x = 1;
  }

  memset(vis, 0, sizeof vis);
  gao(1, 0);

  printf("%d\n", res + calcdis());

  return 0;
}