zoukankan      html  css  js  c++  java
  • poj1741 Tree

    树分治。

    网上有部分人的题解写的啥呀。。。

    按重心进行分治。

    首先O(n)算出以当前点为根depth(u)+depth(v)<=k的(u,v)的个数。

    然后再减去同一个子树里depth(u)+depth(v)<=k的(u,v)的个数。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 10000 + 10;
    const int maxm = 20000 + 10;
    const int inf = 0x3f3f3f3f;
    int g[maxn],v[maxm],next[maxm],c[maxm],eid;
    int n,k,tot,root,cnt,res;
    int size[maxn],maxv[maxn];
    bool vis[maxn];
    int dis[maxn];
    
    void addedge(int a,int b,int C) {
        v[eid]=b; c[eid]=C; next[eid]=g[a]; g[a]=eid++;
        v[eid]=a; c[eid]=C; next[eid]=g[b]; g[b]=eid++;    
    }
    
    void get(int u,int f) {
        size[u]=1; maxv[u]=0;
        for(int i=g[u];~i;i=next[i]) if(v[i]!=f&&!vis[v[i]]) {
            get(v[i],u);
            size[u]+=size[v[i]];
            maxv[u]=max(maxv[u],size[v[i]]);
        }
        maxv[u]=max(maxv[u],tot-size[u]);
        if(maxv[u]<maxv[root]) root=u;
    }
    
    void dfsdis(int u,int d,int f) {
        dis[++cnt]=d;
        for(int i=g[u];~i;i=next[i]) if(v[i]!=f&&!vis[v[i]]) dfsdis(v[i],d+c[i],u);
    }
    
    int calc(int u,int d) {
        int ret=0; cnt=0;
        dfsdis(u,d,0);
        sort(dis+1,dis+cnt+1);
        int i=1,j=cnt;
        while(i<j) {
            while(dis[i]+dis[j]>k&&i<j) j--;
            ret+=j-i;
            i++;
        }
        return ret;
    }
    
    void dfs(int u) {
        if(tot<=1) return;
        root=0; get(u,0); 
        int tmp=root; vis[tmp]=1;
        res+=calc(tmp,0);
        for(int i=g[tmp];~i;i=next[i]) {
            if(!vis[v[i]]) {
                res-=calc(v[i],c[i]);
                tot=size[v[i]]; dfs(v[i]);    
            }
        }
    }
    
    int main() {
        maxv[0]=inf;
        while(scanf("%d%d",&n,&k)==2) {
            if(!n&&!k) break;
            memset(g,-1,sizeof(g)); eid=0;
            memset(vis,0,sizeof(vis)); res=0;
            for(int i=1,u,v,w;i<n;i++) {
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w);
            }
            tot=n; dfs(1);
            printf("%d
    ",res);    
        }
        return 0;
    }
  • 相关阅读:
    237. Delete Node in a Linked List
    430. Flatten a Multilevel Doubly Linked List
    707. Design Linked List
    83. Remove Duplicates from Sorted List
    160. Intersection of Two Linked Lists
    426. Convert Binary Search Tree to Sorted Doubly Linked List
    142. Linked List Cycle II
    类之间的关系
    初始化块
    明确类和对象
  • 原文地址:https://www.cnblogs.com/invoid/p/5653810.html
Copyright © 2011-2022 走看看