gggyt  
没谁离不开谁

  

  dfs序就是相当于把树转化成了一个区间,在区间上进行操作。

void dfs(int u, int fa) {
    l[u]=++key;
    for (int i=head[u]; i!=-1; i=e[i].next) {
        int v=e[i].v;
        if (v!=fa) {
            dfs(v, u);
        }
    }
    r[u]=key;
}

  hdu3887

  题意:问你1-n这些节点的子节点下面有多少个比他小的节点。

  其实仔细看跟树状数组的逆序数很像啊,算是dfs序的入门题了

  从1-n分别对他们的所属的区间[l-1, r]进行操作,对l进行+1的操作。

  因为对小的那个操作就相当于树状数组的逆序数的操作,就可以求出多少个比节点小的了。

/*  gyt
       Live up to every day            */
#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<cstring>
#include<queue>
#include<set>
#include<string>
#include<map>
#include <time.h>
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 100005;
const ll maxm = 1e7;
const ll base = 2333;
const int INF = 1<<30;
const db eps = 1e-8;
const ll mod = 1e9+13;
int l[maxn], r[maxn];
int key, cnt;
struct edge{
    int u, v, next;
}e[maxn*2];
int head[maxn];
int c[maxn];
int ans[maxn];

void init() {
    key=0;  cnt=0;
    memset(c, 0, sizeof(c));
    memset(l, 0, sizeof(l));
    memset(r, 0, sizeof(r));
    memset(ans, 0, sizeof(ans));
    memset(head, -1, sizeof(head));
}
void dfs(int u, int fa) {
    l[u]=++key;
    for (int i=head[u]; i!=-1; i=e[i].next) {
        int v=e[i].v;
        if (v!=fa) {
            dfs(v, u);
        }
    }
    r[u]=key;
}
void add(int u, int v) {
    e[cnt].v=v;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
int lowbit(int x) {
    return x&-x;
}
void updata(int x, int d) {
    while(x<maxn) {
        c[x]+=d;
        x+=lowbit(x);
    }
}
int getsum(int x) {
    int ret=0;
    while(x>0) {
        ret+=c[x];
        x-=lowbit(x);
    }
    return ret;
}
void solve() {
    int n, root;
    while(scanf("%d%d", &n, &root)!=EOF) {
        if (!n&&!root)  break;
        init();
        for (int i=0; i<n-1; i++) {
            int u, v;  scanf("%d%d", &u, &v);
            add(u, v);
            add(v, u);
        }
        dfs(root, -1);
        for (int i=1; i<=n; i++) {
            //cout<<r[i]<<" "<<l[i]<<endl;
            ans[i]=getsum(r[i])-getsum(l[i]-1);
           //cout<<getsum(r[i])<<" " << getsum(l[i]-1)<<endl;
            updata(l[i], 1);
        }
        for (int i=1; i<=n; i++) {
            if(i!=1)  printf(" ");
                printf("%d", ans[i]);
        }
        puts("");
    }
}
int main() {
    int t = 1;
    //freopen("in.txt","r",stdin);
  //  freopen("gcd.out","w",stdout);
    //scanf("%d", &t);
    while(t--)
        solve();
    return 0;
}

 

posted on 2017-07-24 12:13  gggyt  阅读(266)  评论(0编辑  收藏  举报