zoukankan      html  css  js  c++  java
  • POJ 1741 Tree(点分治)

    点分治...模板题吧..只要理解了,实现并不难,随便搞搞...

     ---------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<vector>
     
    #define rep(i, n) for(int i = 0; i < n; ++i)
    #define REP(x) for(edge* e = head[x]; e; e = e->next)
    #define clr(x, c) memset(x, c, sizeof(x))
     
    using namespace std;
     
    const int maxn = 10000 + 5;
    const int inf = 0x7fffffff;
     
    int n, K;
     
    struct edge {
    int to, dist;
    edge* next;
    };
     
    edge* pt;
    edge* head[maxn];
    edge EDGE[maxn << 1];
     
    inline void init() {
    pt = EDGE;
    clr(head, 0);
    }
     
    inline void add(int u, int v, int d) {
    pt->to = v;
    pt->dist = d;
    pt->next = head[u];
    head[u] = pt++;
    }
     
    inline void add_edge(int u, int v, int d) {
    add(u, v, d);
    add(v, u, d);
    }
     
    int size[maxn];
    bool vis[maxn];
     
    int dp(int x, int fa) {
    size[x] = 1;
    REP(x) if(!vis[e->to] && e->to != fa)
    size[x] += dp(e->to, x);
    return size[x];
    }
     
    int root, Min;
    int node_num;
     
    void dfs(int x, int fa) {
    int Max = node_num - size[x];
    REP(x) if(fa != e->to && !vis[e->to]) {
    Max = max(Max, size[e->to]);
    dfs(e->to, x);
    }
    if(Max < Min)
       root = x, Min = Max;
    }
     
    void Dfs(int x) {
    Min = inf;
    node_num = dp(x, -1);
    dfs(x, -1);
    }
     
    vector<int> d;
     
    void DFS(int x, int fa, int dist) {
    d.push_back(dist);
    REP(x) if(!vis[e->to] && fa != e->to)
    DFS(e->to, x, dist + e->dist);
    }
     
    int Count(int x, int dist) {
    d.clear();
    DFS(x, -1, dist);
    sort(d.begin(), d.end());
    int ans = 0, l = 0, r = d.size() - 1;
    while(l < r) {
    while(d[l] + d[r] > K && l < r) r--;
    ans += r - l;
    l++;
    }
    return ans;
    }
     
    int ANS;
     
    void COUNT(int x) {
    Dfs(x);
    vis[root] = 1;
    ANS += Count(root, 0);
    REP(root) if(!vis[e->to])
       ANS -= Count(e->to, e->dist), COUNT(e->to);
    }
     
    inline void COUNT_init() {
    ANS = 0;
    clr(vis, 0);
    }
     
    void work() {
    COUNT_init();
    COUNT(0);
    cout << ANS << " ";
    }
     
    void Read() {
    int u, v, d;
    rep(i, n - 1)
       scanf("%d%d%d", &u, &v, &d), add_edge(u - 1, v - 1, d);
    }
     
    int main() {
    // freopen("test.in", "r", stdin);
    while(cin >> n >> K) {
    if(!n && !K) break;
    init();
    Read();
    work();
    }
    return 0;
    }

      

    ---------------------------------------------------------------------- 

    Tree
    Time Limit: 1000MSMemory Limit: 30000K
    Total Submissions: 12802Accepted: 4079

    Description

    Give a tree with n vertices,each edge has a length(positive integer less than 1001). 
    Define dist(u,v)=The min distance between node u and v. 
    Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k. 
    Write a program that will count how many pairs which are valid for a given tree. 

    Input

    The input contains several test cases. The first line of each test case contains two integers n, k. (n<=10000) The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l. 
    The last test case is followed by two zeros. 

    Output

    For each test case output the answer on a single line.

    Sample Input

    5 4 1 2 3 1 3 1 1 4 2 3 5 1 0 0 

    Sample Output

    8

    Source

  • 相关阅读:
    [LeetCode] Baseball Game
    [Linux] Shell Scripts
    [Linux] 正则表达式与文件格式化处理
    [Linux] 学习bash
    [Linux] vim程序编辑器
    [Linux] 文件与文件系统的压缩打包与备份
    [LeetCode] Reverse Words in a String
    [LeetCode] Reverse Integer
    [国嵌笔记][017][Makefile工程管理]
    [国嵌笔记][016][交叉工具链]
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4509586.html
Copyright © 2011-2022 走看看