Advertisement
Guest User

Untitled

a guest
Jun 6th, 2014
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.31 KB | None | 0 0
  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <iostream>
  4. #include "grader.h"
  5. #include <vector>
  6.  
  7. using namespace std;
  8.  
  9. #define forit(it, S) for(__typeof((S).begin()) it = (S).begin(); it != (S).end(); ++it)
  10. #define maxn 200001
  11. #define F first
  12. #define S second
  13.  
  14. vector <int> tree[maxn];
  15. int cnt, d[maxn], d1[maxn], q[maxn], radius[maxn], p[maxn], d2[maxn], last, was[maxn], par[maxn];
  16. vector <pair <int, int> > g[maxn];
  17. bool used[maxn];
  18. pair <int, int> diam[maxn];
  19.  
  20. int most_distant(int x)
  21. {
  22.     ++last;
  23.     int l = 0, r = 1, res = x;
  24.     d2[x] = 0;
  25.     q[r] = x;
  26.     was[x] = last;
  27.  
  28.     while (l < r)
  29.     {
  30.         int v = q[++l];
  31.  
  32.         forit(it, g[v])
  33.             if (was[it -> F] != last)
  34.             {
  35.                 was[it -> F] = last;
  36.                 q[++r] = it -> F;
  37.                 d2[it -> F] = d2[v] + it -> S;
  38.                 if (d2[res] < d2[it -> F])
  39.                     res = it -> F;
  40.                 par[it -> F] = v;                  
  41.             }
  42.     }
  43.        
  44.     return res;
  45. }
  46.  
  47. int get_center(int x)
  48. {
  49.     most_distant(diam[x].F);
  50.  
  51.     vector <int> path;
  52.    
  53.     for (int v = diam[x].S; v != diam[x].F; v = par[v])
  54.         path.push_back(v);
  55.        
  56.     path.push_back(diam[x].F);
  57.  
  58.     int res = 0;
  59.  
  60.     if (path.size() & 1)
  61.         return d2[most_distant(path[(path.size() + 1) / 2 - 1])];
  62.     else
  63.     {
  64.         int u = d2[most_distant(path[path.size() / 2 - 1])];
  65.         int v = d2[most_distant(path[path.size() / 2])];
  66.  
  67.         return min(u, v);
  68.     }
  69. }
  70.  
  71. void calc_radius(int x)
  72. {
  73.     int fr = most_distant(tree[x][0]);
  74.     int sc = most_distant(fr);
  75.  
  76.     diam[x] = make_pair(fr, sc);
  77.     radius[x] = get_center(x);
  78. }
  79.  
  80. bool cmp(int a, int b)
  81. {
  82.     return radius[a] > radius[b];
  83. }
  84.  
  85. void dfs(int v)
  86. {
  87.     tree[cnt].push_back(v);
  88.     used[v] = 1;
  89.  
  90.     forit(it, g[v])
  91.         if (!used[it -> F])
  92.             dfs(it -> F);
  93. }
  94.  
  95. int travelTime(int n, int m, int l, int a[], int b[], int t[])
  96. {
  97.     for (int i = 0; i < m; ++i)
  98.     {
  99.         g[a[i]].push_back(make_pair(b[i], t[i]));
  100.         g[b[i]].push_back(make_pair(a[i], t[i]));
  101.     }
  102.  
  103.     cnt = 0;
  104.  
  105.     for (int i = 0; i < n; ++i)
  106.         if (!used[i])
  107.         {
  108.             ++cnt;
  109.             dfs(i);
  110.             calc_radius(cnt);
  111.         }          
  112.  
  113.     if (cnt == 1)
  114.         return d2[most_distant(diam[1].F)];
  115.  
  116.     for (int i = 1; i <= cnt; ++i)     
  117.         p[i] = i;
  118.  
  119.     sort(p + 1, p + cnt + 1, cmp);     
  120.  
  121.     int ans = radius[p[1]] + radius[p[2]] + l;
  122.  
  123.     if (cnt > 2)
  124.         ans = max(ans, radius[p[2]] + radius[p[3]] + 2 * l);
  125.  
  126.     for (int i = 1; i <= cnt; ++i)
  127.         ans = max(ans, d2[most_distant(diam[i].F)]);
  128.  
  129.     return ans;
  130. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement