POJ - 1741 Tree

POJ - 1741 

思路:

点分治入门题

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 1e4 + 5;
int head[N], son[N], maxson[N], d[N], cnt = 0, ans = 0, rt, n, k;
bool vis[N];
vector<int>deep;
struct edge {
    int to, w, nxt;
}edge[N*2];
void add_edge(int u, int v, int w) {
    edge[cnt].to = v;
    edge[cnt].w = w;
    edge[cnt].nxt = head[u];
    head[u] = cnt++;
}
void get_rt(int o, int u) {
    son[u] = 1;
    maxson[u] = 0;
    for (int i = head[u]; ~i; i = edge[i].nxt) {
        if(edge[i].to != o && !vis[edge[i].to]) {
            get_rt(u, edge[i].to);
            son[u] += son[edge[i].to];
            maxson[u] = max(maxson[u], son[edge[i].to]);
        }
    }
    maxson[u] = max(maxson[u], n - son[u]);
    if(maxson[u] < maxson[rt]) rt = u;
}
void get_d(int o, int u) {
    deep.pb(d[u]);
    son[u] = 1;
    for (int i = head[u]; ~i; i = edge[i].nxt) {
        if(edge[i].to != o && !vis[edge[i].to]) {
            d[edge[i].to] = d[u] + edge[i].w;
            get_d(u, edge[i].to);
            son[u] += son[edge[i].to];
        }
    }
}
int cal(int u, int dis) {
    deep.clear();
    d[u] = dis;
    get_d(0, u);
    sort(deep.begin(), deep.end());
    int res = 0;
    for (int l = 0, r = deep.size()-1; l < r;) {
        if(deep[l] + deep[r] <= k) res += r - l++;
        else r--;
    }
    return res;
}
void work(int u) {
    ans += cal(u, 0);
    vis[u] = true;
    for (int i = head[u]; ~i; i = edge[i].nxt) {
        if(!vis[edge[i].to]) {

            ans -= cal(edge[i].to, edge[i].w);
            maxson[0] = n = son[edge[i].to];
            get_rt(rt = 0, edge[i].to);
            work(rt);
        }
    }
}
int main() {
    int u, v, w;
    while(~scanf("%d%d", &n, &k) && n && k) {
        mem(head, -1);
        mem(vis, false);
        ans = cnt = 0;
        for (int i = 1; i < n; i++) {
            scanf("%d%d%d", &u, &v, &w);
            add_edge(u, v, w);
            add_edge(v, u, w);
        }
        maxson[0] = n;
        get_rt(rt = 0, 1);
        work(rt);
        printf("%d\n", ans);
    }
    return 0;
}

 2019.3

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<cstdio>
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "\n";
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

const int N = 1e4 + 5;
const int INF = 0x3f3f3f3f;
int son[N], n, k, u, v, w, ans = 0;
vector<pii> g[N];
vector<int> deep;
bool vis[N];
void get_sz(int u, int o) {
    son[u] = 1;
    for (int i = 0; i < g[u].size(); ++i) {
        int v = g[u][i].fi;
        if(!vis[v] && v != o) {
            get_sz(v, u);
            son[u] += son[v];
        }
    }
}
pii get_center(int u, int o, int tot) {
    pii res = mp(INF, -1);
    int m = 0, tmp = 1;
    for (int i = 0; i < g[u].size(); ++i) {
        int v = g[u][i].fi;
        if(!vis[v] && v != o) {
            res = min(res, get_center(v, u, tot));
            m = max(m, son[v]);
            tmp += son[v];
        }
    }
    m = max(m, tot-tmp);
    res = min(res, mp(m, u));
    return res;
}
void get_deep(int u, int o, int d) {
    deep.pb(d);
    for (int i = 0; i < g[u].size(); ++i) {
        int v = g[u][i].fi;
        int w = g[u][i].se;
        if(!vis[v] && v != o) {
            get_deep(v, u, d + w);
        }
    }
}
int cal() {
    int res = 0;
    sort(deep.begin(), deep.end());
    for (int l = 0, r = deep.size()-1; l < r; ) {
        if(deep[l] + deep[r] <= k) res += r - l++;
        else r--;
    }
    deep.clear();
    return res;
}
void solve(int u) {
    get_sz(u, u);
    pii p = get_center(u, u, son[u]);
    int c = p.se;
    vis[c] = true;
    get_deep(c, c, 0);
    ans += cal();
    for (int i = 0; i < g[c].size(); ++i) {
        int v = g[c][i].fi;
        if(!vis[v]) solve(v);
    }
    for (int i = 0; i < g[c].size(); ++i) {
        int v = g[c][i].fi;
        int w = g[c][i].se;
        if(!vis[v]) {
            get_deep(v, v, w);
            ans -= cal();
        }
    }
    vis[c] = false;
}
int main() {
    while(~scanf("%d %d", &n, &k) && (n || k)) {
        for (int i = 1; i <= n; ++i) g[i].clear(), son[i] = 0;
        for (int i = 1; i < n; ++i) scanf("%d %d %d", &u, &v, &w), g[u].pb({v, w}), g[v].pb({u, w});
        ans = 0;
        solve(1);
        printf("%d\n", ans);
    }
    return 0;
}

 

posted @ 2018-05-28 18:19  Wisdom+.+  阅读(147)  评论(0编辑  收藏  举报