QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#54318#853. Flat Organizationckiseki#TL 1ms3584kbC++203.6kb2022-10-07 20:34:322022-10-07 20:34:33

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-10-07 20:34:33]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:3584kb
  • [2022-10-07 20:34:32]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

class SCC {
private:
  int n, cnt;
  vector<vector<int>> rG, G;
  vector<int> ord, idx;
  vector<bool> vis;
  void dfs(int u) {
    vis[u] = true;
    for (int v : G[u])
      if (not vis[v])
        dfs(v);
    ord.push_back(u);
  }
  void rdfs(int u) {
    vis[u] = false;
    idx[u] = cnt;
    for (int v : rG[u])
      if (vis[v])
        rdfs(v);
  }

public:
  void init(int n_) {
    G.clear();
    G.resize(n = n_);
    rG.clear();
    rG.resize(n);
    cnt = 0;
    idx.resize(n);
    ord.clear();
    vis.clear();
    vis.resize(n);
  }
  void add_edge(int u, int v) {
    G[u].push_back(v);
    rG[v].push_back(u);
  }
  void solve() {
    for (int i = 0; i < n; ++i)
      if (not vis[i])
        dfs(i);
    reverse(ord.begin(), ord.end());
    for (int u : ord) {
      if (not vis[u])
        continue;
      rdfs(u);
      cnt++;
    }
  }
  int get_id(int x) const { return idx[x]; }
  int count() const { return cnt; }
} scc;

int main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  int t;
  cin >> t;
  while (t--) {
    int n;
    cin >> n;
    scc.init(n);
    vector<tuple<int, int, int>> e;
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        int w;
        cin >> w;
        if (w == 0)
          continue;
        e.emplace_back(i, j, w);
        scc.add_edge(i, j);
      }
    }
    if (n == 1) {
      cout << "YES\n0 0\n";
      continue;
    }
    if (n == 2) {
      cout << "NO\n";
      continue;
    }
    scc.solve();
    vector<int> ind(scc.count()), oud(scc.count());
    vector<vector<pair<int, int>>> g(scc.count());
    vector<vector<tuple<int, int, int>>> rg(scc.count());
    for (auto [u, v, w] : e) {
      int uu = scc.get_id(u);
      int vv = scc.get_id(v);
      if (uu == vv)
        continue;
      g[vv].emplace_back(uu, w);
      rg[uu].emplace_back(u, v, w);
      ind[uu]++;
      oud[vv]++;
    }
    int o = -1;
    for (int i = 0; i < scc.count(); ++i) {
      if (ind[i] == 0) {
        assert(o == -1);
        o = i;
      }
    }
    assert(o != -1);
    for (int x = o; true;) {
      int nx = -1;
      for (auto [y, _] : g[x]) {
        if (--ind[y] == 0) {
          assert(nx == -1);
          nx = y;
        }
      }
      if (nx == -1)
        break;
      g[nx].emplace_back(x, 0);
      rg[x].emplace_back(-1, nx, 0);
      x = nx;
    }
    vector<int64_t> d(scc.count(), int64_t(1) << 60);
    vector<bool> inq(scc.count());
    d[o] = 0;
    inq[o] = true;
    while (true) {
      pair<int64_t, int> mi = {int64_t(1) << 60, -1};
      for (int i = 0; i < scc.count(); ++i) {
        if (not inq[i])
          continue;
        mi = min(mi, pair{d[i], i});
        inq[i] = false;
      }
      const int u = mi.second;
      if (u == -1)
        break;
      for (auto [v, w] : g[u]) {
        if (d[u] + w < d[v]) {
          d[v] = d[u] + w;
          inq[v] = true;
        }
      }
    }
    for (int i = 0; i < scc.count(); ++i) {
      if (oud[i] == 0) {
        cout << "YES\n";
        vector<pair<int, int>> ans;
        for (int j = i; j != o;) {
          for (auto [u, v, w] : rg[j]) {
            int vv = scc.get_id(v);
            if (d[vv] + w == d[j]) {
              j = vv;
              if (u != -1)
                ans.emplace_back(u, v);
              break;
            }
          }
        }
        cout << ans.size() << ' ' << d[i] << '\n';
        for (auto [u, v] : ans)
          cout << u + 1 << ' ' << v + 1 << '\n';
        break;
      }
    }
  }
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3584kb

input:

1
5
0 1 0 6 11
0 0 1 6 12
2 0 0 7 12
0 0 0 0 4
0 0 0 0 0

output:

YES
2 10
1 4
4 5

result:

ok OK!

Test #2:

score: -100
Time Limit Exceeded

input:

100
5
0 1 0 6 11
0 0 1 6 12
2 0 0 7 12
0 0 0 0 4
0 0 0 0 0
1
0
2
0 0
7 0
2
0 1000000000
0 0
3
0 0 5
6 0 0
0 7 0
3
0 4 6
0 0 0
0 1 0
3
0 4 0
0 0 0
6 3 0
3
0 0 0
10 0 6
3 0 0
3
0 1999999998 1999999999
0 0 1999999998
0 0 0
50
0 105800 801 1800 64800 0 259200 288801 72201 12801 125000 20001 28801 33800 ...

output:


result: