zoukankan      html  css  js  c++  java
  • 点分治

    具体待更

    代码:

      1 #include <bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 #define re register
      6 #define rep(i, a, b) for (re int i = a; i <= b; ++i)
      7 #define repd(i, a, b) for (re int i = a; i >= b; --i)
      8 #define For(i, a, b, s) for (re int i = a; i <= b; s)
      9 #define maxx(a, b) a = max(a, b)
     10 #define minn(a, b) a = min(a, b)
     11 #define LL long long
     12 #define INF (1 << 30)
     13 
     14 inline int read() {
     15     int w = 0, f = 1; char c = getchar();
     16     while (!isdigit(c)) f = c == '-' ? -1 : f, c = getchar();
     17     while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ '0'), c = getchar();
     18     return w * f;
     19 }
     20 
     21 const int maxn = 1e4 + 5, maxm = 100 + 5;
     22 
     23 struct Edge {
     24     int u, v, w, pre;
     25 } e[maxn << 1];
     26 int ec, G[maxn];
     27 void init() { memset(G, -1, sizeof(G)); ec = 0; }
     28 void add(int u, int v, int w) { e[ec++] = (Edge){u, v, w, G[u]}; G[u] = ec-1; }
     29 #define iter(i, u) for (register int i = G[u]; i != -1; i = e[i].pre)
     30 
     31 struct Pair {
     32     int d, id;
     33     bool operator < (const Pair &r) const { return d < r.d; }
     34 } p[maxn];
     35 int N, M;
     36 int ask[maxm], ans[maxm];
     37 int son[maxn], rt, maxp[maxn], vis[maxn], cnt;
     38 
     39 void get_dist(int u, int fa, int rt, int dist) {
     40     son[u] = 1; p[cnt++] = (Pair){dist, rt};
     41     iter(i, u)
     42         if (e[i].v != fa && !vis[e[i].v]) {
     43             get_dist(e[i].v, u, rt, dist + e[i].w);
     44             son[u] += son[e[i].v];
     45         }
     46 }
     47 
     48 int query(int v) {
     49     int l = 0, r = cnt-1, res = cnt;
     50     while (l <= r) {
     51         int mid = (l + r) >> 1;
     52         if (v >= p[mid].d) l = mid+1, res = mid;
     53         else r = mid-1;
     54     }
     55     return res;
     56 }
     57 
     58 void solve(int u) {
     59     cnt = 1;
     60     iter(i, u) {
     61         if (vis[e[i].v]) continue;
     62         get_dist(e[i].v, u, e[i].v, e[i].w);
     63     }
     64     sort(p, p+cnt);
     65     rep(i, 1, M) if (!ans[i])
     66         rep(s, 0, cnt) {
     67             int t = query(ask[i]-p[s].d);
     68             while (p[s].id == p[t].id && p[t].d == p[t+1].d) t++;
     69             if (s == t || p[s].id == p[t].id) continue;
     70             if (p[s].d + p[t].d == ask[i]) {
     71                 ans[i] = 1; break;
     72             }
     73         }
     74 }
     75 
     76 int get_rt(int u, int fa, int sum) {
     77     maxp[u] = 0; int son = 1;
     78     iter(i, u)
     79         if (e[i].v != fa && !vis[e[i].v]) {
     80             int child = get_rt(e[i].v, u, sum);
     81             maxx(maxp[u], child);
     82             son += child;
     83         }
     84     maxx(maxp[u], sum - son);
     85     if (maxp[u] < maxp[rt]) rt = u;
     86     return son;
     87 }
     88 
     89 void divid(int u) {
     90     solve(u); vis[u] = 1;
     91     iter(i, u)
     92         if (!vis[e[i].v]) {
     93             rt = 0;
     94             get_rt(e[i].v, e[i].v, son[e[i].v]);
     95             divid(rt);
     96         }
     97 }
     98 
     99 int main() {
    100     init(); maxp[rt = 0] = INF;
    101     N = read(), M = read();
    102     rep(i, 1, N-1) {
    103         int u = read(), v = read(), w = read();
    104         add(u, v, w); add(v, u, w);
    105     }
    106     rep(i, 1, M) ask[i] = read();
    107     rt = 0; get_rt(1, 1, N); divid(rt);
    108     rep(i, 1, M) printf("%s
    ", ans[i] ? "AYE" : "NAY");
    109     return 0;
    110 }
  • 相关阅读:
    《大道至简》之五
    String类总结
    《大道至简》之沟通
    程序设计及总结
    《大道至简》之团队
    动手动脑课堂作业7---------
    动手动脑课堂作业7
    动手动脑
    大道至简—现实中的软件工程—思考还是思想
    动手动脑
  • 原文地址:https://www.cnblogs.com/ac-evil/p/10426998.html
Copyright © 2011-2022 走看看