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

// #include <bits/stdc++.h>
#include <algorithm>
#include <bitset>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <vector>
using namespace std;
long double esp = 1e-11;
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#define fi first
#define se second
#define all(a) (a).begin(), (a).end()
#define cle(a)                                                                 \\
  while (!a.empty())                                                           \\
  a.pop()
#define mem(p) memset(p, 0, sizeof(p))
#define memf(p) memset(p, 0x3f, sizeof(p))
#define memn(p) memset(p, -1, sizeof(p))
#define mp(A, B) make_pair(A, B)
#define pb push_back
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
typedef long long int LL;
const long double PI = acos((long double)-1);
const LL INF = 0x3f3f3f3fll;
const int MOD = 1000000007;
const int maxn = 110000;
#define V 110
#define E 15100
struct bigint {
  int k[55];
} ept;
bigint binf;
bigint operator+(bigint const &a, bigint const &b) {
  bigint tem;
  for (int x = 0; x < 55; x++)
    tem.k[x] = a.k[x] + b.k[x];
  return tem;
}
bool operator>(bigint const &a, bigint const &b) {
  for (int x = 0; x < 55; x++)
    if (a.k[x] > b.k[x])
      return 1;
    else if (a.k[x] == b.k[x])
      continue;
    else
      return 0;
  return 0;
}
bool operator!=(bigint const &a, bigint const &b) {
  for (int x = 0; x < 55; x++)
    if (a.k[x] != b.k[x])
      return 1;
  return 0;
}
int vis[V];
bigint dist[V];
int pre[V];

struct Edge {
  int u, v, c, next;
  bigint cost;
} edge[E];
int head[V], cnt;

void init() {
  cnt = 0;
  memset(head, -1, sizeof(head));
}
void addedge(int u, int v, int c, bigint cost) {
  edge[cnt].u = u;
  edge[cnt].v = v;
  edge[cnt].cost = cost;
  edge[cnt].c = c;
  edge[cnt].next = head[u];
  head[u] = cnt++;

  for (int x = 0; x < 55; x++)
    cost.k[x] *= -1;
  edge[cnt].u = v;
  edge[cnt].v = u;
  edge[cnt].cost = cost;
  edge[cnt].c = 0;
  edge[cnt].next = head[v];
  head[v] = cnt++;
}

bool spfa(int begin, int end) {
  int u, v;
  queue<int> q;
  for (int i = 0; i <= end + 2; i++) {
    pre[i] = -1;
    vis[i] = 0;
    dist[i] = binf;
  }
  vis[begin] = 1;
  dist[begin] = ept;
  q.push(begin);
  while (!q.empty()) {
    u = q.front();
    q.pop();
    vis[u] = 0;
    for (int i = head[u]; i != -1; i = edge[i].next) {
      if (edge[i].c > 0) {
        v = edge[i].v;
        if (dist[v] > dist[u] + edge[i].cost) {
          dist[v] = dist[u] + edge[i].cost;
          pre[v] = i;
          if (!vis[v]) {
            vis[v] = true;
            q.push(v);
          }
        }
      }
    }
  } // cout << "spfa" << endl;
  return dist[end] != binf;
}

bigint MCMF(int begin, int end) {
  bigint ans = ept;
  int flow;
  int flow_sum = 0;
  while (spfa(begin, end)) {
    flow = INF;
    for (int i = pre[end]; i != -1; i = pre[edge[i].u])
      if (edge[i].c < flow)
        flow = edge[i].c;
    for (int i = pre[end]; i != -1; i = pre[edge[i].u]) {
      edge[i].c -= flow;
      edge[i ^ 1].c += flow;
    }
    ans = ans + dist[end];
    flow_sum += flow;
  }
  // cout << flow_sum << endl;
  return ans;
}
char s[110];
char h[66][66];
int cal(char c) {
  if (c <= 'Z')
    return c - 'A';
  return 26 + c - 'a';
}
char fcal(int x) {
  if (x <= 25)
    return 'A' + x;
  return x - 26 + 'a';
}
int main() {
  // freopen("in.txt", "r", stdin);
  // freopen("inlay.in", "r", stdin);
  // freopen("out.txt", "w", stdout);
  // map<long long int,int>ma;                 %I64d
  // vector<int>::iterator iter;
  // memset(m,0,sizeof(int));
  // for(int x=1;x<=n;x++)
  // for(int y=1;y<=n;y++)
  // scanf("%d%d",&a,&b);
  // scanf("%d",&a);
  // printf("%d\\n",ans);
  mem(ept.k);
  memf(binf.k);
  int n;
  scanf("%d", &n);
  init();
  int st = 105, ed = 106;
  for (int x = 0; x < n; x++)
    addedge(st, x, 1, ept), addedge(n + x, ed, 1, ept);
  bigint tem;
  for (int x = 0; x < n; x++) {
    scanf("%s", s);
    for (int y = 0; y < n; y++) {
      h[x][y] = s[y];
      mem(tem.k);
      tem.k[cal(s[y])] = -1;
      addedge(x, n + y, 1, tem);
    }
  } // printf("%d\\n",1111);
  bigint ans = MCMF(st, ed);
  for (int x = 0; x < 55; x++)
    while (ans.k[x]++)
      putchar(fcal(x));
  puts("");
  // printf("%d\\n",spfa(st,ed));
  /*for(int x=0;x<cnt;x++)
  {
      printf("%d %d %d\\n",edge[x].u,edge[x].v,edge[x].c);
      for(int y=0;y<55;y++)
          if(edge[x].cost.k[y])
              printf("%d ",edge[x].cost.k[y]);
          //printf("%d ",edge[x].cost.k[y]);
      putchar('\\n');
  }*/
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#define LL long long

const int MAXN = 107;
const int MAXM = 0;
const long long LLINF = 9000000000000000000;
const long double INF = 1e233; // careful because of floyed and so on
const int MOD = 1000000007;
double eps = 0.00000001;

using namespace std;

int n;
char s[MAXN][MAXN];
long double v[MAXN];

long double w[MAXN][MAXN];
long double lx[MAXN], ly[MAXN]; //??
int linky[MAXN];
bool visx[MAXN], visy[MAXN];
long double slack[MAXN];
bool find(int x) {
  visx[x] = true;
  for (int y = 1; y <= n; y++) {
    if (visy[y])
      continue;
    int t = lx[x] + ly[y] - w[x][y];
    if (t == 0) {
      visy[y] = true;
      if (linky[y] == -1 || find(linky[y])) {
        linky[y] = x;
        return true;
      }
    } else if (slack[y] > t)
      slack[y] = t;
  }
  return false;
}

int KM() {
  int i, j;

  memset(linky, -1, sizeof(linky));
  memset(ly, 0, sizeof(ly));

  for (i = 1; i <= n; i++) // 初始化??
  {
    lx[i] = -INF;
    for (j = 1; j <= n; j++) {
      if (w[i][j] > lx[i])
        lx[i] = w[i][j];
    }
  }

  for (int x = 1; x <= n; x++) {
    for (i = 1; i <= n; i++)
      slack[i] = INF;
    while (true) {
      memset(visx, 0, sizeof(visx));
      memset(visy, 0, sizeof(visy));
      if (find(x))
        break;
      double d = INF;

      for (i = 1; i <= n; i++) {
        if (!visy[i] && d > slack[i])
          d = slack[i];
      }
      for (i = 1; i <= n; i++) {
        if (visx[i])
          lx[i] -= d;
      }
      for (i = 1; i <= n; i++) {
        if (visy[i])
          ly[i] += d;
        else
          slack[i] -= d;
      }
    }
  }

  int result = 0;
  for (i = 1; i <= n; i++) {
    if (linky[i] > -1) {
      result += w[linky[i]][i];
    }
  }

  return result;
}

int main() {
  v[51] = 1;
  for (int i = 50; i >= 0; i--) {
    v[i] = v[i + 1] * 50;
  }
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%s", s[i] + 1);
    for (int j = 1; j <= n; j++) {
      if (s[i][j] >= 'A' && s[i][j] <= 'Z')
        w[i][j] = v[s[i][j] - 'A'];
      if (s[i][j] >= 'a' && s[i][j] <= 'z')
        w[i][j] = v[s[i][j] - 'a' + 26];
    }
  }
  KM();
  vector<char> ans;
  for (int i = 1; i <= n; i++) {
    ans.push_back(s[linky[i]][i]);
  }
  sort(ans.begin(), ans.end());
  for (int i = 0; i < (int)ans.size(); i++) {
    printf("%c", ans[i]);
  }
  printf("\\n");
  return 0;
}