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

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
int n, m;
const int maxn = 5e4 + 1000;
const int maxv = 600;
struct Edge {
  int u, v, w, next;
  Edge(int _u = 0, int _v = 0, int _w = 0, int _next = 0) {
    u = _u, v = _v;
    w = _w;
    next = _next;
  }
} edge[maxn * 2], tedge[maxn];
int head[maxv], ednum, idx[maxn];
void addedge(int u, int v, int w) {
  edge[ednum] = Edge(u, v, w, head[u]);
  head[u] = ednum++;
  edge[ednum] = Edge(v, u, w, head[v]);
  head[v] = ednum++;
}
bool cmp(int a, int b) { return tedge[a].w < tedge[b].w; }
int dfn[maxv], low[maxv], idxn, stnum, sccnum, stk[maxv], scc[maxv];
bool inst[maxv];
void tarjan(int u, int pre) {
  int i, v;
  dfn[u] = low[u] = ++idxn;
  inst[u] = true;
  stk[stnum++] = u;
  for (i = head[u]; i != -1; i = edge[i].next) {
    v = edge[i].v;
    // cout <<u<<" "<<v<<" "<<i<<" "<<edge[i].next<<endl;getchar();
    if (v == pre)
      continue;
    if (!dfn[v]) {
      tarjan(v, u);
      low[u] = min(low[u], low[v]);
    } else if (inst[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (low[u] == dfn[u]) {
    ++sccnum;
    while (stk[stnum - 1] != u) {
      scc[stk[stnum - 1]] = sccnum;
      inst[stk[stnum - 1]] = false;
      stnum--;
    }
    scc[stk[stnum - 1]] = sccnum;
    inst[stk[stnum - 1]] = false;
    stnum--;
  }
}
bool isaim[maxn];
int main() {
  int i, j, u, v, w;
  int num, ans;
  scanf("%d %d", &n, &m);
  for (i = 0; i < m; i++) {
    idx[i] = i;
    scanf("%d %d %d", &u, &v, &w);
    tedge[i] = Edge(u, v, w);
  }
  num = ans = ednum = 0;
  memset(head, -1, sizeof(head));
  memset(isaim, false, sizeof(isaim));
  sort(idx, idx + m, cmp);
  for (i = 0; i < m; i++) {
    if (i == 0 || tedge[idx[i]].w == tedge[idx[i - 1]].w)
      addedge(tedge[idx[i]].u, tedge[idx[i]].v, tedge[idx[i]].w);
    else {
      memset(dfn, 0, sizeof(dfn));
      memset(scc, 0, sizeof(scc));
      memset(inst, false, sizeof(inst));
      idxn = 0;
      sccnum = 0;
      for (j = 1; j <= n; j++)
        if (!dfn[j]) {
          stnum = 0;
          tarjan(j, -1);
        }
      // cout <<i<<":";for(j=1;j<=n;j++)cout <<scc[j]<<" ";cout <<endl;
      for (j = 0; j < i; j++)
        if (scc[tedge[idx[j]].u] != scc[tedge[idx[j]].v])
          isaim[idx[j]] = true;
      addedge(tedge[idx[i]].u, tedge[idx[i]].v, tedge[idx[i]].w);
    }
  }
  memset(dfn, 0, sizeof(dfn));
  memset(scc, 0, sizeof(scc));
  memset(inst, false, sizeof(inst));
  idxn = 0;
  sccnum = 0;
  for (j = 1; j <= n; j++)
    if (!dfn[j]) {
      stnum = 0;
      tarjan(j, -1);
    }
  // cout <<i<<":";for(j=1;j<=n;j++)cout <<scc[j]<<" ";cout <<endl;
  for (j = 0; j < m; j++)
    if (scc[tedge[idx[j]].u] != scc[tedge[idx[j]].v])
      isaim[idx[j]] = true;
  for (j = 0; j < m; j++)
    if (isaim[j])
      num++, ans += tedge[j].w;
  printf("%d %d\\n", num, ans);
  return 0;
}

Error: TLE

Fixed submission:

/*************************************************************************
    > File Name: 4.cpp
    > Author: cy
    > Mail: 1002@qq.com
    > Created Time: 15/5/13 21:09:07
 ************************************************************************/

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <vector>

const int maxn = 1000 + 5;

#define inf 0x3f3f3f3f
//  #define INF 0x3FFFFFFFFFFFFFFFLL
#define rep(i, n) for (i = 0; i < n; i++)
#define reP(i, n) for (i = 1; i <= n; i++)

#define ull unsigned long long
#define ll long long

#define cle(a) memset(a, 0, sizeof(a))

using namespace std;
#define N 510
#define INF 500000

int mm[N][N], low[N]; // low表示i的所有??的最小??
bool bz[N];           // bz表示??数?
int v, e;             // v表示楼个数, e表示?系数
int xx[50005], yy[50005], zz[50005];
int prim(); // 返回最小生成数的??

int main() {
#ifndef ONLINE_JUDGE
  // freopen("in.txt","r",stdin);
  // freopen("out.txt","w",stdout);
#endif
  int i;
  scanf("%d%d", &v, &e);
  int x, y, z;

  memset(mm, -1, sizeof(mm));
  for (i = 1; i <= v; i++)
    mm[i][i] = 0;
  for (i = 1; i <= v; i++) {
    for (int j = 1; j <= v; j++) {
      if (i != j)
        mm[i][j] = 1000;
    }
  }
  ll cot = 0;
  for (i = 0; i < e; i++) {
    scanf("%d%d%d", &x, &y, &z);
    mm[x][y] = z;
    xx[i] = x;
    yy[i] = y;
    zz[i] = z;
    mm[y][x] = z;
    cot += z;
  }

  memset(bz, 0, sizeof(bz));
  memset(low, -1, sizeof(low));
  int ans = prim();
  ll num = e;
  for (i = 0; i < e; i++) {
    mm[xx[i]][yy[i]] = 10000;
    mm[yy[i]][xx[i]] = 10000;
    memset(bz, 0, sizeof(bz));
    memset(low, -1, sizeof(low));
    int temp = prim();
    if (ans == temp) {
      num--;
      cot -= zz[i];
    }
    mm[xx[i]][yy[i]] = zz[i];
    mm[yy[i]][xx[i]] = zz[i];
  }
  cout << num << " " << cot << endl;
  return 0;
}

int prim() {
  int i, j, ans = 0, choose; // ans是??， choose是当前??的?点?号
  for (i = 1; i <= v; i++)
    low[i] = mm[1][i]; // 默?从1?始，建立low表
  low[1] = 0;
  bz[1] = 1;
  for (i = 1; i < v; i++) {
    int min = INF;
    for (j = 1; j <= v; j++) {
      if (!bz[j] && low[j] != -1 && low[j] < min) {
        min = low[j]; //?找??点所有??中??最小的一个
        choose = j;   //????的?点
      }
    }
    ans += low[choose];        //?入?数
    bz[choose] = 1;            //??走?
    for (j = 1; j <= v; j++) { // 遍?起点?choose的所有??，并更新low表
      if (!bz[j] && mm[choose][j] != -1 &&
          (mm[choose][j] < low[j] || low[j] == -1))
        low[j] = mm[choose][j]; // 更新low表
    }
  }

  return ans;
}