Problem p04010 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <vector>
#define SF scanf
#define PF printf
#define MAXN 100010
using namespace std;
typedef long long ll;
int n, m;
struct node {
  int x;
  node *nxt;
} edge[MAXN * 2];
node *head[MAXN], *ncnt = edge;
void add_edge(int u, int v) {
  ++ncnt;
  ncnt->x = v;
  ncnt->nxt = head[u];
  head[u] = ncnt;
}
int dep[MAXN], ods[MAXN], cirlen, sum[MAXN], tot, cu, cv;
bool vis[MAXN];
ll ans;
void dfs(int x, int f) {
  vis[x] = 1;
  dep[x] = dep[f] ^ 1;
  if (dep[x] == 0)
    sum[x] = 1;
  else
    sum[x] = -1;
  tot += sum[x];
  for (node *v = head[x]; v != NULL; v = v->nxt) {
    int u = v->x;
    if (u == f)
      continue;
    if (vis[u] == 1) {
      cirlen = dep[u] ^ dep[x] ^ 1;
      cu = x;
      cv = u;
      continue;
    }
    dfs(u, x);
  }
}
void solve(int x, int f) {
  vis[x] = 1;
  for (node *v = head[x]; v != NULL; v = v->nxt) {
    int u = v->x;
    if (u == f || vis[u] == 1)
      continue;
    solve(u, x);
    ods[x] += ods[u];
    sum[x] += sum[u];
  }
}
int A[MAXN], cnt;
int main() {
  SF("%d%d", &n, &m);
  int u, v;
  for (int i = 1; i <= m; i++) {
    SF("%d%d", &u, &v);
    add_edge(u, v);
    add_edge(v, u);
  }
  dfs(1, 0);
  if (n == m + 1) {
    if (tot != 0) {
      PF("-1");
      return 0;
    }
  } else {
    if (cirlen == 1) {
      if (tot % 2 != 0) {
        PF("-1");
        return 0;
      }
      sum[cu] -= tot / 2;
      sum[cv] -= tot / 2;
      ans += abs(tot / 2);
    } else {
      while (1)
        ;
      if (tot != 0) {
        PF("-1");
        return 0;
      }
      ods[cu] = 1;
      ods[cv] = -1;
    }
  }
  memset(vis, 0, sizeof vis);
  solve(1, 0);
  for (int i = 1; i <= n; i++) {
    if (ods[i] == 0)
      ans += abs(sum[i]);
    else {
      if (ods[i] == 1)
        sum[i] = -sum[i];
      A[++cnt] = sum[i];
    }
  }
  if (cirlen == 0 && cu != 0) {
    A[++cnt] = 0; // LCA of cu and cv
    sort(A + 1, A + 1 + cnt);
    ll mid = A[(cnt + 1) / 2];
    for (int i = 1; i <= cnt; i++)
      ans += abs(A[i] - mid);
  }
  PF("%lld", ans);
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <vector>
#define SF scanf
#define PF printf
#define MAXN 100010
using namespace std;
typedef long long ll;
int n, m;
struct node {
  int x;
  node *nxt;
} edge[MAXN * 2];
node *head[MAXN], *ncnt = edge;
void add_edge(int u, int v) {
  ++ncnt;
  ncnt->x = v;
  ncnt->nxt = head[u];
  head[u] = ncnt;
}
int dep[MAXN], ods[MAXN], cirlen, sum[MAXN], tot, cu, cv;
bool vis[MAXN];
ll ans;
void dfs(int x, int f) {
  vis[x] = 1;
  dep[x] = dep[f] ^ 1;
  if (dep[x] == 0)
    sum[x] = 1;
  else
    sum[x] = -1;
  tot += sum[x];
  for (node *v = head[x]; v != NULL; v = v->nxt) {
    int u = v->x;
    if (u == f)
      continue;
    if (vis[u] == 1) {
      cirlen = dep[u] ^ dep[x] ^ 1;
      cu = x;
      cv = u;
      continue;
    }
    dfs(u, x);
  }
}
void solve(int x, int f) {
  vis[x] = 1;
  for (node *v = head[x]; v != NULL; v = v->nxt) {
    int u = v->x;
    if (u == f || vis[u] == 1)
      continue;
    solve(u, x);
    ods[x] += ods[u];
    sum[x] += sum[u];
  }
}
int A[MAXN], cnt;
int main() {
  SF("%d%d", &n, &m);
  int u, v;
  for (int i = 1; i <= m; i++) {
    SF("%d%d", &u, &v);
    add_edge(u, v);
    add_edge(v, u);
  }
  dfs(1, 0);
  if (n == m + 1) {
    if (tot != 0) {
      PF("-1");
      return 0;
    }
  } else {
    if (cirlen == 1) {
      if (tot % 2 != 0) {
        PF("-1");
        return 0;
      }
      sum[cu] -= tot / 2;
      sum[cv] -= tot / 2;
      ans += abs(tot / 2);
    } else {
      if (tot != 0) {
        PF("-1");
        return 0;
      }
      ods[cu] = 1;
      ods[cv] = -1;
    }
  }
  memset(vis, 0, sizeof vis);
  solve(1, 0);
  for (int i = 1; i <= n; i++) {
    if (ods[i] == 0)
      ans += abs(sum[i]);
    else {
      if (ods[i] == 1)
        sum[i] = -sum[i];
      A[++cnt] = sum[i];
    }
  }
  if (cirlen == 0 && cu != 0) {
    A[++cnt] = 0; // LCA of cu and cv
    sort(A + 1, A + 1 + cnt);
    ll mid = A[(cnt + 1) / 2];
    for (int i = 1; i <= cnt; i++)
      ans += abs(A[i] - mid);
  }
  PF("%lld", ans);
}