Advertisement
Guest User

Untitled

a guest
Jun 20th, 2019
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.20 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4.  
  5. struct tedge {
  6.   string u, v;
  7.   int k;
  8.   char t;
  9. };
  10. enum type {
  11.   RED, BLACK
  12. };
  13. struct edge {
  14.   int u, v;
  15.   type t;
  16.   ll len;
  17.   int cnt;
  18.  
  19.   bool operator== (const edge &ed) const {
  20.     //return u == ed.u && v == ed.v ;//&& t == ed.t;
  21.     return ((u == ed.u && v == ed.v) || (u == ed.v && v == ed.u));
  22.   }
  23.  
  24.   int go(int x) {
  25.     assert(x == u || x == v);
  26.     return x ^ u ^ v;
  27.   }
  28. };
  29. int common(edge e1, edge e2) {
  30.   //cout << e1.u << " " << e1.v << " " << e1.t << endl;
  31.   //cout << e2.u << " " << e2.v << " " << e2.t << endl;
  32.   assert(!(e1 == e2));
  33.   if (e2.u == e1.v || e2.v == e1.v) return e1.v;
  34.   if (e2.u == e1.u || e2.v == e1.u) return e1.u;
  35.   return -1;
  36. }
  37.  
  38. struct dsu {
  39.   int n;
  40.   vector<int> p;
  41.  
  42.   dsu(int _n) {
  43.     n = _n;
  44.     p.resize(n);
  45.     iota(p.begin(), p.end(), 0);
  46.   }
  47.  
  48.   int get(int x) {
  49.     return x == p[x] ? x : p[x] = get(p[x]);
  50.   }
  51.  
  52.   void uni(int u, int v) {
  53.     p[get(v)] = get(u);
  54.   }
  55. };
  56.  
  57. vector<edge> find_cycle(vector<edge> ed) {
  58.   int n = 0;
  59.   for (auto o : ed) {
  60.     n = max(n, o.u + 1);
  61.     n = max(n, o.v + 1);
  62.   }
  63.   int m = ed.size();
  64.  
  65.   vector<vector<vector<int>>> e(n, vector<vector<int>>(2));
  66.   for (int i = 0; i < m; i++) {
  67.     int t = ed[i].t == BLACK;
  68.     e[ed[i].u][t].push_back(i);
  69.     e[ed[i].v][t].push_back(i);
  70.   }
  71.   for (int i = 0; i < n; i++) assert(e[i][0].size() == e[i][1].size());
  72.  
  73.   vector<char> used(m);
  74.   vector<int> ans;
  75.   function<void(int, int)> go = [&](int v, int t) {
  76.     while (1) {
  77.       while (!e[v][t].empty() && used[e[v][t].back()]) e[v][t].pop_back();
  78.       if (e[v][t].empty()) return;
  79.       int id = e[v][t].back();
  80.       used[id] = 1;
  81.       go(ed[id].go(v), t ^ 1);
  82.       ans.push_back(id);
  83.     }
  84.   };
  85.   go(0, 0);
  86.   for (int i = 0; i < m; i++) assert(used[i]);
  87.  
  88.   assert((int)ans.size() == m);
  89.   vector<edge> res;
  90.   for (int i = 0; i < m; i++) res.push_back(ed[ans[i]]);
  91.  
  92.   for (int i = 0; i < m; i++) {
  93.     //cout << res[(i + 0) % m].u << " " << res[(i + 0) % m].v << " " << res[(i + 0) % m].t << endl;
  94.     //cout << res[(i + 1) % m].u << " " << res[(i + 1) % m].v << " " << res[(i + 1) % m].t << endl;
  95.     assert(common(res[i], res[(i + 1) % m]) != -1);
  96.     assert(res[i].t != res[(i + 1) % m].t);
  97.   }
  98.  
  99.   return res;
  100. }
  101.  
  102. vector<edge> solve_connected(vector<edge> ed) {
  103.   if (ed.empty()) return ed;
  104.   vector<int> v;
  105.   for (auto o : ed) {
  106.     v.push_back(o.u);
  107.     v.push_back(o.v);
  108.   }
  109.   sort(v.begin(), v.end());
  110.   v.resize(unique(v.begin(), v.end()) - v.begin());
  111.   auto getId = [&](int x) {
  112.     return (int)(lower_bound(v.begin(), v.end(), x) - v.begin());
  113.   };
  114.   int n = v.size();
  115.  
  116.   for (auto &o : ed) {
  117.     o.u = getId(o.u);
  118.     o.v = getId(o.v);
  119.     if (o.u > o.v) swap(o.u, o.v);
  120.   }
  121.  
  122.   set<pair<int, int>> st;
  123.   for (auto o : ed) {
  124.     if (o.t == RED) {
  125.       st.insert({o.u, o.v});
  126.     }
  127.   }
  128.   vector<edge> ned;
  129.   for (auto o : ed) {
  130.     if (o.t == BLACK && st.find({o.u, o.v}) != st.end()) {
  131.       ned.push_back({o.u, n, BLACK, 0, 0});
  132.       ned.push_back({n, n + 1, RED, o.len, o.cnt});
  133.       ned.push_back({o.v, n + 1, BLACK, 0, 0});
  134.       n += 2;
  135.     } else ned.push_back(o);
  136.   }
  137.   ed = ned;
  138.  
  139.   vector<int> deg(n);
  140.   for (auto o : ed) {
  141.     if (o.t == RED) {
  142.       deg[o.u]++;
  143.       deg[o.v]++;
  144.     } else {
  145.       deg[o.u]--;
  146.       deg[o.v]--;
  147.     }
  148.   }
  149.  
  150.  
  151.   int sum = 0;
  152.   for (int i = 0; i < n; i++) {
  153.     assert(deg[i] >= 0);
  154.     sum += deg[i];
  155.   }
  156.  
  157.   if (sum) {
  158.     n += 2;
  159.     for (int i = 0; i < n - 2; i++) {
  160.       for (int j = 0; j < deg[i]; j++) {
  161.         ed.push_back({i, n - 2, BLACK, 0, 0});
  162.       }
  163.     }
  164.     assert(sum % 2 == 0);
  165.     for (int i = 0; i < sum / 2; i++) {
  166.       ed.push_back({n - 2, n - 1, RED, 0, 0});
  167.       ed.push_back({n - 2, n - 1, RED, 0, 0});
  168.       ed.push_back({n - 1, n - 1, BLACK, 0, 0});
  169.     }
  170.   }
  171.  
  172.   auto cycle = find_cycle(ed);
  173.   for (int i = 0; i < (int)cycle.size(); i++) {
  174.     int c = common(cycle[i], cycle[(i + 1) % cycle.size()]);
  175.     assert(c != -1);
  176.     if (cycle[i].v != c) swap(cycle[i].u, cycle[i].v);
  177.     if (cycle[(i + 1) % cycle.size()].u != c) swap(cycle[(i + 1) % cycle.size()].u, cycle[(i + 1) % cycle.size()].v);
  178.   }
  179.  
  180.   for (int any = 1; any;) {
  181.     any = 0;
  182.     for (int i = 0; i + 2 < (int)cycle.size(); i++) {
  183.       if (cycle[i].t == BLACK) {
  184.         assert(cycle[i + 1].t == RED);
  185.         assert(cycle[i + 2].t == BLACK);
  186.  
  187.         //int b = common(cycle[i], cycle[i + 1]);
  188.         int a = cycle[i].u;
  189.         assert(cycle[i].v == cycle[i + 1].u);
  190.         int b = cycle[i].v;
  191.         assert(cycle[i + 1].v == cycle[i + 2].u);
  192.         int c = cycle[i + 1].v;
  193.         int D = cycle[i + 2].v;
  194.        
  195.         if (a == n - 2 || b == n - 2 || c == n - 2 || D == n - 2) continue;
  196.  
  197.         int kx = 0;
  198.         vector<edge> et;
  199.         vector<edge> oth;
  200.         int kz = 0;
  201.         for (int j = 0; j < (int)cycle.size(); j++) {
  202.           if (cycle[j] == cycle[i]) {
  203.             kx++;
  204.           } else {
  205.             if (cycle[j].t == RED || cycle[j] == cycle[i + 2] || (cycle[j].u != c && cycle[j].v != c)) {
  206.               kz += cycle[j] == cycle[i + 2];
  207.               oth.push_back(cycle[j]);
  208.             } else {
  209.               et.push_back(cycle[j]);
  210.             }
  211.           }
  212.         }
  213.         int kt = et.size();
  214.         int ky = 0;
  215.         for (int j = 0; j < (int)cycle.size(); j++) {
  216.           if (cycle[j].t == BLACK && !(cycle[j] == cycle[i]) && (cycle[j].u == b || cycle[j].v == b)) {
  217.             ky++;
  218.           }
  219.         }
  220.         //if (kt != 0 || ky != 0) continue;
  221.         //cout << kx << " " << kt << " " << kz << endl;
  222.        
  223.         bool can_compress = 0;
  224.  
  225.         //if (kx > kt) cerr << kx << " " << et.size() << endl;
  226.         if (kt < kx) {
  227.           can_compress = 1;
  228.         } else if (kt == kx) {
  229.           for (auto o : et) {
  230.             oth.push_back({a, o.go(c), BLACK, 0, 0});
  231.           }
  232.           dsu d(n);
  233.           int k = kx;
  234.           for (auto o : oth) {
  235.             if (o == cycle[i + 1] && k-- > 0) continue;
  236.             d.uni(o.u, o.v);
  237.           }
  238.           can_compress = 0;
  239.           for (int j = 1; j < (int)oth.size(); j++) if (d.get(oth[j].u) != d.get(oth[0].u)) can_compress = 1;
  240.         } else {
  241.           dsu d(n);
  242.           for (auto o : oth) d.uni(o.u, o.v);
  243.           set<int> ss;
  244.           for (auto o : oth) ss.insert(d.get(o.u));
  245.           can_compress = (int)ss.size() >= (int)et.size() + 2;
  246.         }
  247.  
  248.         if (can_compress) {
  249.           any = 1;
  250.           edge nw;
  251.           nw.u = a;
  252.           nw.v = D;
  253.           nw.t = BLACK;
  254.           nw.len = cycle[i].len + cycle[i + 1].len + cycle[i + 2].len;
  255.           nw.cnt = cycle[i].cnt + cycle[i + 1].cnt + cycle[i + 2].cnt;
  256.  
  257.           cycle.erase(cycle.begin() + i);
  258.           cycle.erase(cycle.begin() + i);
  259.           cycle.erase(cycle.begin() + i);
  260.           cycle.insert(cycle.begin() + i, nw);
  261.           assert(cycle[i].u == cycle[(i - 1 + cycle.size()) % cycle.size()].v);
  262.           assert(cycle[i].v == cycle[i + 1].u);
  263.           i--;
  264.         }
  265.       }
  266.     }
  267.   }
  268.  
  269.   return cycle;
  270. }
  271.  
  272. void solve(string file) {
  273.   ifstream in(file);
  274.   string s;
  275.  
  276.   vector<tedge> ted;
  277.   while (getline(in, s)) {
  278.     stringstream ss;
  279.     ss << s;
  280.    
  281.     string v, u;
  282.     int k;
  283.     char t;
  284.     ss >> v >> u >> k >> t;
  285.     ted.push_back({v, u, k, t});
  286.   }
  287.   auto getPos = [&](string t) {
  288.     ll res = 0;
  289.     for (char c : t) {
  290.       if (c >= '0' && c <= '9') res = 10 * res + (c - '0');
  291.       else res = 0;
  292.     }
  293.     return res;
  294.   };
  295.   vector<string> vct;
  296.   for (auto o : ted) {
  297.     vct.push_back(o.u);
  298.     vct.push_back(o.v);
  299.   }
  300.   sort(vct.begin(), vct.end());
  301.   vct.resize(unique(vct.begin(), vct.end()) - vct.begin());
  302.   int n = vct.size();
  303.   auto getId = [&](string ss) {
  304.     return (int)(lower_bound(vct.begin(), vct.end(), ss) - vct.begin());
  305.   };
  306.  
  307.   vector<edge> ed;
  308.   for (auto o : ted) {
  309.     edge ced;
  310.     ced.u = getId(o.u);
  311.     ced.v = getId(o.v);
  312.     if (ced.u > ced.v) swap(ced.u, ced.v);
  313.     ced.t = o.t == 'S' ? RED : BLACK;
  314.     ced.len = abs(getPos(o.u) - getPos(o.v));
  315.     ced.cnt = 1;
  316.     while (o.k--) {
  317.       ed.push_back(ced);
  318.     }
  319.   }
  320.  
  321.   dsu d(n);
  322.   for (auto o : ed) {
  323.     d.uni(o.u, o.v);
  324.   }
  325.  
  326.   vector<vector<edge>> ned(n);
  327.   for (auto o : ed) {
  328.     ned[d.get(o.u)].push_back(o);
  329.   }
  330.  
  331.   vector<int> lens;
  332.   for (auto v : ned) {
  333.     auto res = solve_connected(v);
  334.     for (auto o : res) {
  335.       if (o.cnt > 0) {
  336.         lens.push_back(o.cnt);
  337.       }
  338.     }
  339.   }
  340.   sort(lens.begin(), lens.end());
  341.  
  342.   double av = 0;
  343.   for (int x : lens) av += x;
  344.   av /= lens.size();
  345.  
  346.   vector<int> nres;
  347.   for (int x : lens) for (int i = 0; i < x; i++) nres.push_back(x);
  348.   sort(nres.begin(), nres.end());
  349.   int m50 = nres[nres.size() / 2];
  350.  
  351.   cout.precision(3); cout << fixed;
  352.   cout << "solve test " << file << endl;
  353.   cout << "number of edges: " << ed.size() << " -> " << lens.size() << endl;
  354.   cout << "number of original edges in one compressed edge:" << endl;
  355.   cout << "average: " << av << endl;
  356.   cout << "m50: " << m50 << endl;
  357.   cout << endl;
  358. }
  359.  
  360. int main(int argc, char* argv[]) {
  361.   for (int i = 1; i < argc; i++) {
  362.     solve(argv[i]);
  363.   }
  364. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement