国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

POJ - 1987 樹分治

2019-11-11 07:00:49
字體:
來源:轉載
供稿:網友

題意:

與POJ-1741一致,傳送門:點擊打開鏈接

思路:

沒什么意思,直接套模板

代碼:

#include <cstdio>#include <cstring>#include <iostream>#include <vector>#include <algorithm>using namespace std;typedef long long ll;const int MAXN = 1e5 + 10;struct node {    int v;    ll w;};ll k;int n, m, root, Max, ans;vector <node> tree[MAXN];vector <ll> dis;int sz[MAXN], maxv[MAXN];bool vis[MAXN];void init() {    memset(vis, false, sizeof(vis));    for (int i = 1; i <= n; i++) tree[i].clear();}void dfs_size(int u, int PRe) {         // 求出每個子樹的大小,以及每個節點的最大兒子    sz[u] = 1; maxv[u] = 0;    int cnt = tree[u].size();    for (int i = 0; i < cnt; i++) {        int v = tree[u][i].v;        if (v == pre || vis[v]) continue;        dfs_size(v, u);        sz[u] += sz[v];        maxv[u] = max(maxv[u], sz[v]);    }}void dfs_root(int r, int u, int pre) {  // 找出以u為根的子樹的重心    maxv[u] = max(maxv[u], sz[r] - sz[u]);    if (Max > maxv[u]) {        Max = maxv[u];        root = u;    }    int cnt = tree[u].size();    for (int i = 0; i < cnt; i++) {        int v = tree[u][i].v;        if (v == pre || vis[v]) continue;        dfs_root(r, v, u);    }}void dfs_dis(int u, int pre, int d) {    // 求出當前子樹中所有點到根的距離    dis.push_back(d);    int cnt = tree[u].size();    for (int i = 0; i < cnt; i++) {        int v = tree[u][i].v, w = tree[u][i].w;        if (v == pre || vis[v]) continue;        dfs_dis(v, u, d + w);    }}int cal(int u, int d) {         // 計算當前子樹中合法的點對數    int res = 0;    dis.clear(); dfs_dis(u, -1, d);    sort (dis.begin(), dis.end());    int i = 0, j = dis.size() - 1;    while (i < j) {        while (dis[i] + dis[j] > k && i < j) --j;        res += j - i;        ++i;    }    return res;}void dfs(int u) {               // 總的dfs求解    Max = n;    dfs_size(u, -1); dfs_root(u, u, -1);    ans += cal(root, 0);    vis[root] = true;    int cnt = tree[root].size(), rt = root; // 一定要注意這樣里的root是全局變量,在遞歸之后可能改變,需要提前保存下來。    for (int i = 0; i < cnt; i++) {        int v = tree[rt][i].v, w = tree[rt][i].w;        if (vis[v]) continue;        ans -= cal(v, w);        dfs(v);    }}int main() {    //freopen("in", "r", stdin);    while (scanf("%d%d", &n, &m) == 2) {        init();        char s[10];        for (int i = 1; i < n; i++) {            int u, v;            ll w;            scanf("%d%d%lld%s", &u, &v, &w, s);            tree[u].push_back((node){v, w});            tree[v].push_back((node){u, w});        }        scanf("%lld", &k);        ans = 0;        dfs(1);        printf("%d/n", ans);    }    return 0;}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 监利县| 崇信县| 田东县| 枣庄市| 宾阳县| 金乡县| 瑞安市| 壶关县| 肇州县| 玉林市| 城口县| 龙口市| 正蓝旗| 曲沃县| 正定县| 云安县| 龙泉市| 花莲县| 襄城县| 双峰县| 江华| 辽宁省| 鄄城县| 苍梧县| 汝阳县| 修水县| 洪江市| 宜昌市| 辽宁省| 武冈市| 丹江口市| 孟津县| 平山县| 林州市| 赤城县| 枣阳市| 岳池县| 长垣县| 繁昌县| 土默特左旗| 岳池县|