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

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define REP(i, x) for (int i = 0; i < (int)(x); i++)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define RREP(i, x) for (int i = ((int)(x)-1); i >= 0; i--)
#define RFOR(i, c)                                                             \\
  for (__typeof((c).rbegin()) i = (c).rbegin(); i != (c).rend(); i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a, b) make_pair(a, b)
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &t) {
  os << "[";
  FOR(it, t) {
    if (it != t.begin())
      os << ",";
    os << *it;
  }
  os << "]";
  return os;
}
template <class T> ostream &operator<<(ostream &os, const set<T> &t) {
  os << "{";
  FOR(it, t) {
    if (it != t.begin())
      os << ",";
    os << *it;
  }
  os << "}";
  return os;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &t) {
  return os << "(" << t.first << "," << t.second << ")";
}

const double EPS = 1e-8;
const int MOD = 1000000007;

typedef double Weight;
const Weight INF = 99999999;
struct Edge {
  int src, dst;
  Weight weight;
  int rev;
  Edge(int f, int t, Weight c, int rev = 0)
      : src(f), dst(t), weight(c), rev(rev) {}
};
typedef vector<vector<Edge>> Graph;

void add_edge(Graph &G, int s, int t, Weight cap) {
  G[s].push_back(Edge(s, t, cap, G[t].size()));
  G[t].push_back(Edge(t, s, 0, G[s].size() - 1));
}

void bfs(const Graph &G, vector<int> &level, int s) {
  level[s] = 0;
  queue<int> que;
  que.push(s);
  while (!que.empty()) {
    int v = que.front();
    que.pop();
    REP(i, G[v].size()) {
      const Edge &e = G[v][i];
      if (e.weight > 1e-8 && level[e.dst] < 0) {
        level[e.dst] = level[v] + 1;
        que.push(e.dst);
      }
    }
  }
}
Weight dfs(Graph &G, vector<int> &level, vector<int> &iter, int v, int t,
           Weight flow) {
  if (v == t)
    return flow;
  for (int &i = iter[v]; i < (int)G[v].size(); i++) {
    Edge &e = G[v][i];
    if (e.weight > 0 && level[v] < level[e.dst]) {
      Weight d = dfs(G, level, iter, e.dst, t, min(flow, e.weight));
      if (d > 0) {
        e.weight -= d;
        G[e.dst][e.rev].weight += d;
        return d;
      }
    }
  }
  return 0;
}

// Dinic
// O(EV^2)
Weight max_flow(Graph &G, int s, int t) {
  Weight flow = 0;
  while (true) {
    vector<int> level(G.size(), -1);
    vector<int> iter(G.size(), 0);
    bfs(G, level, s);
    if (level[t] < 0)
      break; // もう流せない
    Weight f = 0;
    while ((f = dfs(G, level, iter, s, t, INF)) > 0) {
      flow += f;
    }
  }
  return flow;
}

int n, h;
double b[101], c[101][101];
vi ans;
pair<double, vi> solve(int req, double t) {
  Graph g(n + 2);
  REP(i, n) {
    add_edge(g, n, i, b[i]);
    add_edge(g, i, n + 1, i == req ? 1e8 : t);
    REP(j, n) if (i != j) { add_edge(g, i, j, c[i][j]); }
  }
  const double cost = max_flow(g, n, n + 1) - n * t;
  pair<double, vi> res(cost, vi());
  FOR(e, g[n]) if (e->weight < 1e-8) res.second.push_back(e->dst);
  return res;
}

pair<double, vi> solve2(double t) {
  Graph g(n + 2);
  REP(i, n) {
    add_edge(g, n, i, b[i]);
    add_edge(g, i, n + 1, t);
    REP(j, n) if (i != j) { add_edge(g, i, j, c[i][j]); }
  }
  const double cost1 = max_flow(g, n, n + 1) - n * t;
  if (cost1 > EPS)
    return make_pair(cost1, vi(n + 1));
  double cost2 = INF;
  int q = 0;
  queue<int> que;
  vi visited(n + 2, 1);
  que.push(n);
  visited[n] = visited[n + 1] = 0;
  while (!que.empty()) {
    int v = que.front();
    que.pop();
    FOR(e, g[v]) if (e->weight * 100 > EPS && visited[e->dst]) {
      visited[e->dst] = 0;
      que.push(e->dst);
    }
  }
  return make_pair(cost1 + !accumulate(ALL(visited), 0), visited);
}

int main() {
  ios::sync_with_stdio(false);
  for (int T = 1; cin >> n >> h, n; ++T) {
    REP(i, n) cin >> b[i];
    REP(i, n) REP(j, n) cin >> c[i][j];
    vi ans;
    double l = 0.0, r = 2000.0;
    REP(itr, 60) {
      double med = (l + r) / 2;
      auto res = solve2(med);
      //			cout << itr << ", " << med << ", " << res.first
      //<< ", " << res.second << endl;
      if (res.first < 1e-8) {
        ans = res.second;
        r = med;
      } else
        l = med;
    }
    //		ans = solve(solve2(l).second, l).second;
    printf("Case %d:\\n", T, l);
    int lSl = accumulate(ALL(ans), 0);
    vector<double> qqq(n);
    REP(i, n) qqq[i] = ans[i] ? (double)h / lSl : 0.0;
    double sum = 0;
    REP(i, n) sum += qqq[i] * b[i];
    REP(i, n) REP(j, n) sum += abs(qqq[i] - qqq[j]) * c[i][j];
    //		printf("%.10f\\n", sum/h);

    REP(i, n)
    printf("%.15f%s", ans[i] ? (double)h / lSl : 0.0, i + 1 == n ? "\\n" : " ");
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <valarray>
#include <vector>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define REP(i, x) for (int i = 0; i < (int)(x); i++)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define RREP(i, x) for (int i = ((int)(x)-1); i >= 0; i--)
#define RFOR(i, c)                                                             \\
  for (__typeof((c).rbegin()) i = (c).rbegin(); i != (c).rend(); i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a, b) make_pair(a, b)
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &t) {
  os << "[";
  FOR(it, t) {
    if (it != t.begin())
      os << ",";
    os << *it;
  }
  os << "]";
  return os;
}
template <class T> ostream &operator<<(ostream &os, const set<T> &t) {
  os << "{";
  FOR(it, t) {
    if (it != t.begin())
      os << ",";
    os << *it;
  }
  os << "}";
  return os;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &t) {
  return os << "(" << t.first << "," << t.second << ")";
}

const double EPS = 1e-8;
const int MOD = 1000000007;

typedef double Weight;
const Weight INF = 99999999;
struct Edge {
  int src, dst;
  Weight weight;
  int rev;
  Edge(int f, int t, Weight c, int rev = 0)
      : src(f), dst(t), weight(c), rev(rev) {}
};
typedef vector<vector<Edge>> Graph;

void add_edge(Graph &G, int s, int t, Weight cap) {
  G[s].push_back(Edge(s, t, cap, G[t].size()));
  G[t].push_back(Edge(t, s, 0, G[s].size() - 1));
}

void bfs(const Graph &G, vector<int> &level, int s) {
  level[s] = 0;
  queue<int> que;
  que.push(s);
  while (!que.empty()) {
    int v = que.front();
    que.pop();
    REP(i, G[v].size()) {
      const Edge &e = G[v][i];
      if (e.weight > 1e-8 && level[e.dst] < 0) {
        level[e.dst] = level[v] + 1;
        que.push(e.dst);
      }
    }
  }
}
Weight dfs(Graph &G, vector<int> &level, vector<int> &iter, int v, int t,
           Weight flow) {
  if (v == t)
    return flow;
  for (int &i = iter[v]; i < (int)G[v].size(); i++) {
    Edge &e = G[v][i];
    if (e.weight > 0 && level[v] < level[e.dst]) {
      Weight d = dfs(G, level, iter, e.dst, t, min(flow, e.weight));
      if (d > 0) {
        e.weight -= d;
        G[e.dst][e.rev].weight += d;
        return d;
      }
    }
  }
  return 0;
}

// Dinic
// O(EV^2)
Weight max_flow(Graph &G, int s, int t, double th = INF) {
  Weight flow = 0;
  while (true) {
    if (flow > th + 1e-8)
      break;
    vector<int> level(G.size(), -1);
    vector<int> iter(G.size(), 0);
    bfs(G, level, s);
    if (level[t] < 0)
      break; // もう流せない
    Weight f = 0;
    while ((f = dfs(G, level, iter, s, t, INF)) > 0) {
      flow += f;
    }
  }
  return flow;
}

int n, h;
double b[101], c[101][101];
vi ans;
pair<double, vi> solve(int req, double t) {
  Graph g(n + 2);
  REP(i, n) {
    add_edge(g, n, i, b[i]);
    add_edge(g, i, n + 1, i == req ? 1e8 : t);
    REP(j, n) if (i != j) { add_edge(g, i, j, c[i][j]); }
  }
  const double cost = max_flow(g, n, n + 1) - n * t;
  pair<double, vi> res(cost, vi());
  FOR(e, g[n]) if (e->weight < 1e-8) res.second.push_back(e->dst);
  return res;
}

pair<double, int> solve2(double t) {
  Graph g(n + 2);
  REP(i, n) {
    add_edge(g, n, i, b[i]);
    add_edge(g, i, n + 1, t);
    REP(j, n) if (i != j) { add_edge(g, i, j, c[i][j]); }
  }
  const double cost1 = max_flow(g, n, n + 1, t) - n * t;
  if (cost1 > EPS)
    return make_pair(cost1, 0);
  double cost2 = INF;
  int q = 0;
  REP(i, n) {
    Graph g2(g);
    g2[n][i].weight += INF;
    if (chmin(cost2, max_flow(g2, n, n + 1, -cost1)))
      q = i;
  }
  return make_pair(cost1 + cost2, q);
}

int main() {
  ios::sync_with_stdio(false);
  for (int T = 1; cin >> n >> h, n; ++T) {
    REP(i, n) cin >> b[i];
    REP(i, n) REP(j, n) cin >> c[i][j];
    vi ans;
    int t;
    double l = 0.0, r = 2000.0;
    REP(itr, 40) {
      double med = (l + r) / 2;
      auto res = solve2(med);
      t = res.first;
      //			cout << i << ", " << med << ", " << res.first <<
      //", " << res.second << endl;
      if (res.first < 1e-8)
        r = med;
      else
        l = med;
    }
    ans = solve(t, l).second;
    printf("Case %d\\n", T);
    REP(i, n)
    printf("%.10f%s",
           find(ALL(ans), i) != ans.end() ? (double)h / ans.size() : 0.0,
           i + 1 == n ? "\\n" : " ");
  }
  return 0;
}