mr_dot_convict

472D-codeforces-mr.convict

Oct 6th, 2019
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.36 KB | None | 0 0
  1. // Hack it and have it ;) //
  2. /*author* Priyanshu Shrivastav (from IIT Palakkad) *
  3.  * *_ __ ___  _ ______ ___  _ ____   ___  ___| |_  *
  4.  * | '_ ` _ \| '__/ __/ _ \| '_ \ \ / / |/ __| __| *
  5.  * | | | | | | | | (_| (_) | | | \ V /| | (__| |_  *
  6.  * |_| |_| |_|_|(_)___\___/|_| |_|\_/ |_|\___|\__| *
  7. When I wrote this, only God and I understood what I was doing
  8.  ** * * * * * * * Now, only God knows!* * * * * * */
  9. #include      <bits/stdc++.h>
  10. #include      <ext/pb_ds/assoc_container.hpp>
  11. #include      <ext/pb_ds/tree_policy.hpp>
  12. using namespace std;
  13. using namespace __gnu_pbds;
  14.  
  15. #ifndef CONVICTION
  16. #pragma GCC       optimize ("Ofast")
  17. #pragma GCC       optimize ("unroll-loops")
  18. #pragma GCC       target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  19. #endif
  20.  
  21. #define IOS       ios_base::sync_with_stdio(false); cin.tie (nullptr)
  22. #define PREC      cout.precision (10); cout << fixed
  23. #define x         first
  24. #define y         second
  25. #define fr(i,x,y) for (int i = x; i <= y; ++i)
  26. #define fR(i,x,y) for (int i = x; i >= y; --i)
  27. #define bg(x)     " [ " << #x << " : " << (x) << " ] "
  28. #define un(x)     sort(x.begin(), x.end()), \
  29.                   x.erase(unique(x.begin(), x.end()), x.end())
  30.  
  31. using   ll  =     long long;
  32. using   ull =     unsigned long long;
  33. using   ff  =     long double;
  34. using   pii =     pair<int,int>;
  35. using   pil =     pair<int,ll>;
  36. typedef tree
  37. < int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
  38. ordered_set;
  39.  
  40. struct chash {
  41.    int operator () (pii x) const { return x.x*31 + x.y; }
  42. };
  43. gp_hash_table <pii, int, chash> mp;
  44.  
  45. #if __cplusplus > 201103L
  46. seed_seq seq{
  47.    (uint64_t) chrono::duration_cast<chrono::nanoseconds>
  48.       (chrono::high_resolution_clock::now().time_since_epoch()).count(),
  49.       (uint64_t) __builtin_ia32_rdtsc(),
  50.       (uint64_t) (uintptr_t) make_unique<char>().get()
  51. };
  52. mt19937 rng(seq); //uniform_int_distribution<int> (l, h)(rng); //[low, high]
  53. #else
  54. auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
  55. mt19937 rng(seed);
  56. #endif
  57.  
  58. #define debug(args...) { \
  59.    /* WARNING : do NOT compile this debug func calls with following flags: // \
  60.     * // -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_FORTIFY_SOURCE=2*/ \
  61.    string _s = #args; replace(_s.begin(), _s.end(), ',', ' ');\
  62.    stringstream _ss(_s); \
  63.    istream_iterator<string> _it(_ss); err(_it, args); \
  64. }
  65. void err(istream_iterator<string> it) {
  66.    it->empty(); cerr << " (Line : " << __LINE__ << ")" << '\n';
  67. }
  68. template<typename T, typename... Args>
  69. void err(istream_iterator<string> it, T a, Args... args) {
  70.    cerr << fixed << setprecision(15)
  71.       << " [ " <<  *it << " : " << a  << " ] "<< ' ';
  72.    err(++it, args...);
  73. }
  74. /*****************************************************************************/
  75. //Don’t practice until you get it right. Practice until you can’t get it wrong
  76.  
  77. struct Edge {
  78.    int u, v, w;
  79.    bool operator < (const Edge& other) const {
  80.       return w < other.w;
  81.    }
  82. };
  83.  
  84. bool kruskal(int n, vector<Edge> &edges, vector <vector <pii>> &T) {
  85.    vector <int> rnk(n, 1), rep(n, -1);
  86.  
  87.    for (int i = 0; i < n; ++i) {
  88.       rep[i] = i, rnk[i] = 1;
  89.    }
  90.  
  91.    auto find_set = [&] (int u) -> int {
  92.       int x = u, temp;
  93.       while (rep[u] != u)
  94.          u = rep[u];
  95.       while (rep[x] != x)
  96.          temp = rep[x], rep[x] = u, x = temp;
  97.       return u;
  98.    };
  99.  
  100.    auto merge_set = [&] (int u, int v) -> void {
  101.       int rep_u = find_set(u);
  102.       int rep_v = find_set(v);
  103.       if (rnk[rep_u] > rnk[rep_v]) rep[rep_v] = rep_u;
  104.       else rep[rep_u] = rep_v;
  105.       if (rnk[rep_u] == rnk[rep_v]) ++rnk[rep_v];
  106.    };
  107.  
  108.    sort(edges.begin(), edges.end());
  109.    int edge_cnt = 0;
  110.    for (Edge e : edges) {
  111.       int u = e.u, v = e.v, w = e.w;
  112.       if (find_set(u) == find_set(v)) {
  113.          continue;
  114.       }
  115.       T[u].push_back(make_pair(v, w));
  116.       T[v].push_back(make_pair(u, w));
  117.       merge_set(u, v);
  118.       ++edge_cnt;
  119.    }
  120.    return (edge_cnt == n - 1);
  121. }
  122.  
  123. signed main() {
  124.    IOS; PREC;
  125.  
  126.    int n;
  127.    cin >> n;
  128.    vector <vector <int>> d(n, vector <int>(n, -1));
  129.    vector <vector <int>> dist(n, vector <int>(n, INT_MAX));
  130.    vector <vector<pii>> T(n, vector<pii>());
  131.    vector <Edge> edges;
  132.    bool ok = true;
  133.  
  134.    for (int i = 0; i < n; ++i) {
  135.       for (int j = 0; j < n; ++j) {
  136.          cin >> d[i][j];
  137.          edges.push_back({i, j, d[i][j]});
  138.          if (d[j][i] != -1 && d[j][i] != d[i][j])
  139.             ok = false;
  140.  
  141.          if ((i == j && d[i][j] != 0) || (i != j && d[i][j] == 0)) {
  142.             ok = false;
  143.          }
  144.       }
  145.    }
  146.  
  147.    // apply kruskal and get adjacecy list
  148.    bool is_mst = kruskal(n, edges, T);
  149.  
  150.    if (ok && is_mst) {
  151.       for (int i = 0; i < n; ++i) {
  152.          dist[i][i] = 0;
  153.          function <void(int, int)> dfs =
  154.             [&] (int u, int pr) -> void {
  155.                for (auto v_pair : T[u]) {
  156.                   int v = v_pair.x, w = v_pair.y;
  157.                   if (v == pr) continue;
  158.                   dist[i][v] = dist[i][u] + w;
  159.                   dfs(v, u);
  160.                }
  161.             };
  162.          dfs(i, -1);
  163.       }
  164.  
  165.       for (int i = 0; i < n && ok; ++i) {
  166.          for (int j =  i; j < n && ok; ++j) {
  167.             if (d[i][j] != dist[i][j]) {
  168.                ok = false;
  169.             }
  170.          }
  171.       }
  172.    }
  173.  
  174.    cout << (ok ? "YES\n" : "NO\n");
  175.  
  176.    return EXIT_SUCCESS;
  177. }
Add Comment
Please, Sign In to add comment