zoukankan      html  css  js  c++  java
  • [bzoj2783][JLOI2012]树_树的遍历

    树 bzoj2783 JLOI2012

    题目大意:给定一棵n个点的树。求满足条件的路径条数。说一个路径是满足条件的,当且仅当这条路径上每个节点深度依次递增且点权和为S。

    注释:$1le nle 10^5$,$1le S,val_ile 10^3$。


    想法:翻lijinnn的blog翻到的水题。

    我们直接遍历整棵树,遍历的时候维护全局桶。然后在回溯的时候将这个点对应的dis删除。这样遍历到每个点时桶内对应的就是这个点到根节点的dis桶,直接统计答案即可。

    最后,附上丑陋的代码... ...

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #define N 100010
    using namespace std;
    multiset<int>s;
    bool v[N];
    int to[N],nxt[N],head[N];
    int w[N];
    int tot,sum;
    int root;
    int ans=0;
    inline char nc()
    {
    	static char *p1,*p2,buf[100000];
    	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    int read()
    {
    	int x=0; char c=nc();
    	while(!isdigit(c)) c=nc();
    	while(isdigit(c)) x=(x<<3)+(x<<1)+c-'0',c=nc();
    	return x;
    }
    inline void add(int x,int y)
    {
    	to[++tot]=y;
    	nxt[tot]=head[x];
    	head[x]=tot;
    }
    void dfs(int x,int pre,int data)
    {
    	s.insert(data);
    	int tmp=data+w[x];
    	ans+=s.count(tmp-sum);
    	for(int i=head[x];i;i=nxt[i])
    		dfs(to[i],x,tmp);
    	s.erase(data);
    }
    int main()
    {
    	int n=read(); sum=read();
    	for(int i=1;i<=n;i++) w[i]=read();
    	for(int x,y,i=1;i<n;i++)
    	{
    		x=read(),y=read();
    		add(x,y); v[y]=1;
    	}
    	for(int i=1;i<=n;i++) if(!v[i]) root=i;
    	dfs(root,0,0);
    	printf("%d",ans);
    	return 0;
    }
    

    小结:裙子的简单数据结构的例题。

  • 相关阅读:
    Codeforces 723d [暴力dfs]
    Codeforces 723e [图论][欧拉回路]
    Hihocoder 1035 [树形dp]
    Codeforces 721C [dp][拓扑排序]
    Codeforces 721D [贪心]
    info
    关于string操作
    Floyd求最小环 HDU1599
    Codeforces Round #572 (Div. 2) B Number Circle
    A. XXXXX
  • 原文地址:https://www.cnblogs.com/ShuraK/p/9537232.html
Copyright © 2011-2022 走看看