EntropyIncreaser

CF 891C envy

Nov 25th, 2017
326
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.74 KB | None | 0 0
  1. #include <cstdio>
  2.  
  3. #include <algorithm>
  4.  
  5. #define LOG(FMT...) // fprintf(stderr, FMT)
  6.  
  7. using namespace std;
  8.  
  9. struct node {
  10.     int id, w;
  11.    
  12.     bool operator<(const node& x) const
  13.     { return w < x.w; }
  14. };
  15.  
  16. struct edge {
  17.     int v;
  18.     bool pred;
  19.     edge *next, *rev;
  20. };
  21.  
  22. struct query {
  23.     int qi, ei;
  24.    
  25.     bool operator<(const query& x) const;
  26. };
  27.  
  28. const int N = 500010;
  29.  
  30. int n, m, q;
  31. int eu[N], ev[N], ew[N], f[N], rk[N];
  32. node e[N];
  33. query qu[N];
  34. bool ans[N], vis[N];
  35. edge* g[N];
  36.  
  37. void link(int u, int v);
  38. edge* add_edge(int u, int v);
  39. int find(int x);
  40. void merge(int x, int y);
  41. bool dfs(int u);
  42.  
  43. int main() {
  44.     int cnt = 0, k, l, r;
  45.     scanf("%d%d", &n, &m);
  46.     for (int i = 1; i <= m; ++i) {
  47.         e[i].id = i;
  48.         scanf("%d%d%d", &eu[i], &ev[i], &e[i].w);
  49.         ew[i] = e[i].w;
  50.     }
  51.     scanf("%d", &q);
  52.     for (int i = 1; i <= q; ++i) {
  53.         scanf("%d", &k);
  54.         while (k--) {
  55.             ++cnt;
  56.             qu[cnt].qi = i;
  57.             scanf("%d", &qu[cnt].ei);
  58.         }
  59.     }
  60.    
  61.     sort(e + 1, e + m + 1);
  62.     stable_sort(qu + 1, qu + cnt + 1);
  63.     l = 1;
  64.     for (int i = 1; i <= n; ++i)
  65.         f[i] = i;
  66.     for (int i = 1; i <= m; ++i) {
  67.         if (e[i].w != e[i - 1].w)
  68.             while (ew[qu[l].ei] == e[i].w) {
  69.                 r = l;
  70.                 while (r <= cnt &&
  71.                        ew[qu[r + 1].ei] == e[i].w &&
  72.                        qu[r + 1].qi == qu[r].qi)
  73.                     ++r;
  74.                 for (int j = l; j <= r; ++j)
  75.                     link(find(eu[qu[j].ei]), find(ev[qu[j].ei]));
  76.                 for (int j = l; j <= r; ++j)
  77.                     if (!vis[find(eu[qu[j].ei])])
  78.                         if (dfs(find(eu[qu[j].ei]))) {
  79.                             ans[qu[j].qi] = true;
  80.                             break;
  81.                         }
  82.                 for (int j = l; j <= r; ++j) {
  83.                     g[find(eu[qu[j].ei])] = NULL;
  84.                     g[find(ev[qu[j].ei])] = NULL;
  85.                     vis[find(eu[qu[j].ei])] = false;
  86.                     vis[find(ev[qu[j].ei])] = false;
  87.                 }
  88.                 LOG("%d %d\n", l, r);
  89.                 l = r + 1;
  90.             }
  91.         merge(eu[e[i].id], ev[e[i].id]);
  92.     }
  93.    
  94.     for (int i = 1; i <= q; ++i)
  95.         puts(ans[i] ? "NO" : "YES");
  96.     return 0;
  97. }
  98.  
  99. inline edge* add_edge(int u, int v) {
  100.     static edge pool[N << 1];
  101.     static edge* p = pool;
  102.     ++p;
  103.     p->v = v;
  104.     p->next = g[u];
  105.     g[u] = p;
  106.     return p;
  107. }
  108.  
  109. inline void link(int u, int v) {
  110.     LOG("[INFO] LINKING %d %d\n", u, v);
  111.     edge *p = add_edge(u, v), *q = add_edge(v, u);
  112.     p->rev = q;
  113.     q->rev = p;
  114. }
  115.  
  116. int find(int x) {
  117.     if (f[x] == x)
  118.         return x;
  119.     return f[x] = find(f[x]);
  120. }
  121.  
  122. inline void merge(int x, int y) {
  123.     x = find(x);
  124.     y = find(y);
  125.     if (x == y)
  126.         return;
  127.     if (rk[x] < rk[y])
  128.         f[x] = y;
  129.     else if (rk[y] < rk[x])
  130.         f[y] = x;
  131.     else {
  132.         ++rk[y];
  133.         f[x] = y;
  134.     }
  135. }
  136.  
  137. bool dfs(int u) {
  138.     if (vis[u])
  139.         return true;
  140.     vis[u] = true;
  141.     for (edge* p = g[u]; p; p = p->next)
  142.         if(!p->pred) {
  143.             p->rev->pred = true;
  144.             if (dfs(p->v))
  145.                 return true;
  146.         }
  147.     return false;
  148. }
  149.  
  150. bool query::operator<(const query& x) const
  151. { return ew[ei] < ew[x.ei]; }
Advertisement
Add Comment
Please, Sign In to add comment