Advertisement
Guest User

TaskC SNSS18 Round 2

a guest
Aug 24th, 2018
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.55 KB | None | 0 0
  1. import algoribrary.io.InputReader;
  2. import java.io.PrintWriter;
  3. import java.util.Arrays;
  4.  
  5. public final class TaskС {
  6.     public void solve(int __, InputReader in, PrintWriter out) {
  7.         int citiesQty = in.nextInt();
  8.         int roadsQty = in.nextInt();
  9.         int days = in.nextInt();
  10.         int[] degree = new int[citiesQty];
  11.         int[] u = new int[roadsQty];
  12.         int[] v = new int[roadsQty];
  13.         int[] destroyTime = new int[roadsQty];
  14.         int[] count = new int[days];
  15.         int[][] order = new int[days][];
  16.         for (int i = 0; i < roadsQty; ++i) {
  17.             u[i] = in.nextInt() - 1;
  18.             v[i] = in.nextInt() - 1;
  19.             degree[u[i]]++;
  20.             degree[v[i]]++;
  21.             destroyTime[i] = in.nextInt();
  22.             count[days - destroyTime[i]]++;
  23.         }
  24.         for (int i = 0; i < days; ++i) {
  25.             order[i] = new int[count[i]];
  26.             count[i] = 0;
  27.         }
  28.         for (int i = 0; i < roadsQty; ++i) {
  29.             int time = days - destroyTime[i];
  30.             order[time][count[time]++] = i;
  31.         }
  32.         DSU dsu = new DSU(citiesQty + roadsQty);
  33.         for (int i = 0; i < citiesQty; ++i) {
  34.             dsu.allocate(days, 1);
  35.         }
  36.         for (int[] roads : order) {
  37.             for (int road : roads) {
  38.                 int vp = dsu.get(v[road]);
  39.                 int up = dsu.get(u[road]);
  40.                 if (vp == up) continue;
  41.                 int p = dsu.allocate(destroyTime[road], 0);
  42.                 dsu.unite(vp, p);
  43.                 dsu.unite(up, p);
  44.             }
  45.         }
  46.         int[][] graph = buildGraph(citiesQty, roadsQty, degree, u, v);
  47.         long[] fees = new long[dsu.size()];
  48.         Arrays.fill(fees, -1);
  49.         int[] queue = new int[citiesQty];
  50.         int[] time = new int[citiesQty];
  51.         Arrays.fill(time, -1);
  52.         int head = 0;
  53.         int tail = 0;
  54.         queue[tail++] = 0;
  55.         time[0] = 0;
  56.         long answer = 0;
  57.         while (head < tail) {
  58.             int current = queue[head++];
  59.             answer = Math.max(answer, go(current, dsu, fees));
  60.             for (int edge : graph[current]) {
  61.                 int next = current ^ v[edge] ^ u[edge];
  62.                 if (time[next] != -1 || destroyTime[edge] <= time[current]) continue;
  63.                 time[next] = time[current] + 1;
  64.                 queue[tail++] = next;
  65.             }
  66.         }
  67.         out.println(answer);
  68.     }
  69.  
  70.     private int[][] buildGraph(int citiesQty, int roadsQty, int[] degree, int[] u, int[] v) {
  71.         int[][] graph = new int[citiesQty][];
  72.         for (int i = 0; i < citiesQty; ++i) {
  73.             graph[i] = new int[degree[i]];
  74.             degree[i] = 0;
  75.         }
  76.         for (int i = 0; i < roadsQty; ++i) {
  77.             graph[v[i]][degree[v[i]]++] = i;
  78.             graph[u[i]][degree[u[i]]++] = i;
  79.         }
  80.         return graph;
  81.     }
  82.  
  83.     private long go(int vertex, DSU dsu, long[] fees) {
  84.         if (fees[vertex] == -1) {
  85.             int parent = dsu.parent[vertex];
  86.             if (parent == vertex) { // root
  87.                 fees[vertex] = (long) dsu.size[vertex] * dsu.time[vertex];
  88.             } else {
  89.                 long parentFee = go(parent, dsu, fees);
  90.                 fees[vertex] = parentFee + (long) dsu.size[vertex] * (dsu.time[vertex] - dsu.time[parent]);
  91.             }
  92.         }
  93.         return fees[vertex];
  94.     }
  95.  
  96.     static class DSU {
  97.         final int[] parent;
  98.         final int[] compressed;
  99.         final int[] size;
  100.         final int[] time;
  101.         int payload = 0;
  102.  
  103.         DSU(int capacity) {
  104.             parent = new int[capacity];
  105.             compressed = new int[capacity];
  106.             size = new int[capacity];
  107.             time = new int[capacity];
  108.         }
  109.  
  110.         int allocate(int t, int s) {
  111.             int id = payload;
  112.             parent[payload] = id;
  113.             compressed[payload] = id;
  114.             time[payload] = t;
  115.             size[payload] = s;
  116.             payload++;
  117.             return id;
  118.         }
  119.  
  120.         int size() {
  121.             return payload;
  122.         }
  123.  
  124.         int get(int v) {
  125.             int p = compressed[v];
  126.             if (parent[p] == p) {
  127.                 return p;
  128.             }
  129.             p = get(parent[p]);
  130.             compressed[v] = p;
  131.             return p;
  132.         }
  133.  
  134.         void unite(int v, int p) {
  135.             if (parent[p] != p) {
  136.                 throw new IllegalArgumentException();
  137.             }
  138.             v = get(v);
  139.             assert v != p;
  140.             parent[v] = p;
  141.             size[p] += size[v];
  142.         }
  143.     }
  144. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement