zoukankan      html  css  js  c++  java
  • dfs序理解-hdu3887

      

      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;
    }
  • 相关阅读:
    在windows桌面显示IP等信息的小工具分享
    oracle,根据查询结果结构创建新表
    Oracle多表关联如何更新多个字段
    我想实现一个通用的配置读写类
    【转】Android程序右上角不显示3个点的菜单
    python发送 IBM lotus Notes 邮件
    当超过端口MTU时
    为什么telnet可以用来检查TCP端口是否正常?
    55+手绘网站设计 – 构建极具创新效果的网站
    炫酷动态静图40例——多图杀猫
  • 原文地址:https://www.cnblogs.com/gggyt/p/7228273.html
Copyright © 2011-2022 走看看