zoukankan      html  css  js  c++  java
  • 函数路径Croc Champ 2013 Round 2 题解java教程

    发一下牢骚和主题无关:

        目题接链:

        擒贼先擒王,每次赛后总结CF的题,我都爱好先搞E题,而且E题一般是我最爱的数据结构题,搞起来特爽

        E题:给你一棵树,求满意距离之和<=L 且 路径上的权值之和<= w的点对量数。。。

        类似的目题:http://poj.org/problem?id=1741 

        方法是点的分治,详细参考漆子超的论文,分治算法在树的路径中的应用,论文里头经已讲了很详细了

        会了poj 1741的话,其实这道题就是多了一个制限,还是排序,扫描,不过在求的时候须要用树状组数维护一下,其实很简单,不过我还是调试了良久,,,,,代码力能与思维力能都须要精雕细琢啊。

        在求一个二元组序列有多少对满意件条时卡了良久,看大神们都是加了一个0 0进去,我就是不想加,于是越写越烦,不是少算就是多算,最后冷静下来新重想了想,那还是先算成两倍的吧

        我的那个calc函数略挫,,,,

        poj 1741

        

    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    const int MAX_N = 100010;
    struct Edge{
    	int b , w;
    	Edge() {}
    	Edge(int b,int w): b(b),w(w){
    	}
    };
    #define Tr(it,x) for(vector<Edge>::iterator it = x.begin(); it!=x.end();it++)
    vector<Edge> edge[MAX_N];
    int N , K;
    int size[MAX_N]  ;
    int opt[MAX_N];
    bool del[MAX_N] ;
    long long  Ans ;
    vector<int>  tnode;
    void Dfs(int u,int fa)
    {
    	tnode.push_back(u);
    	opt[u] = 0;
    	size[u] = 1;
    	Tr(it,edge[u])
    	{
    		int v = it->b;
    		if(!del[v] && v!=fa){
    			Dfs(v , u);
    			opt[u] = max(opt[u],size[v]);
    			size[u] += size[v];	
    		}
    	}
    }
    int Find(int u) // find the centre of gravity
    {
    	Dfs(u,-1);
    	int who = -1 , mx = MAX_N;
    	for(vector<int>::iterator it = tnode.begin(); it != tnode.end(); it++)
    	{
    		opt[*it] = max(opt[*it],size[u]-size[*it]);
    		if(mx > opt[*it]) {
    			mx = opt[*it];
    			who = *it;
    		}
    	}
    	return who;
    }
    vector<int> all , ch[MAX_N];
    void Get_dis(int u,int fa,int len,vector<int> &ch)
    {
    	ch.push_back(len);
    	all.push_back(len);
    	Tr(it,edge[u])
    	{
    		if(it->b!=fa && !del[it->b]) {
    			Get_dis(it->b,u,len+it->w,ch);
    		}
    	}
    }
    long long calc(vector<int> dist) 
    {
     	long long ans  = 0;
    	int pt = 0 , sz = dist.size();
    	sort(dist.begin(),dist.end());
    	for(int i = 0,j = sz - 1;i <= j;i++) 
    	{
    		while(i <= j && dist[i] + dist[j] > K) {
    			j--;
    		}
    		if(i < j) ans += j - i;
    	}
    	return ans;
    }
    void Solve(int u)
    {
    	tnode.clear();
    	u = Find(u); // the gravity center 
    	all.clear(); // all of the distances
    	int nch = 0; // count of sons 
    	all.push_back(0);
    	Tr(it,edge[u])
    	{
    		ch[nch].clear(); 
    		if(!del[it->b]) Get_dis(it->b,u,it->w,ch[nch++]);
    	}	
    	Ans += calc(all);
    	for(int i = 0; i < nch; i++)  Ans -= calc(ch[i]);	
    
    	del[u] = true;
    	Tr(it,edge[u])
    		if(!del[it->b])  Solve(it->b);
    }
    int main()
    {
    	int a,b,w;
    	while(scanf("%d%d",&N,&K),N||K)
    	{
    		 for(int i = 1; i <= N; i++) edge[i].clear(),del[i]=false;
             for(int i = 1; i < N; i++)
    		 {
    			 scanf("%d%d%d",&a,&b,&w);
    			 edge[a].push_back(Edge(b,w));
    			 edge[b].push_back(Edge(a,w));
    		 }
    		 Ans = 0;
    		 Solve(1);
    		 printf("%I64d\n",Ans);
    	}
    	return 0;
    }
        每日一道理
    生活中受伤难免,失败跌倒并不可怕,可怕的是因此而一蹶不振,失去了对人生的追求与远大的理想。没有一个人的前进道路是平平稳稳的,就算是河中穿梭航行的船只也难免颠簸,生活中所遇上的坎坷磨难不是偶尔给予的为难,而是必然所经受的磨练。

        CROC round2 E

    // http://poj.org/problem?id=1741
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    const int MAX_N = 100010;
    struct Edge{
    	int b , w;
    	Edge() {}
    	Edge(int b,int w): b(b),w(w){
    	}
    };
    #define Tr(it,x) for(vector<Edge>::iterator it = x.begin(); it!=x.end();it++)
    vector<Edge> edge[MAX_N];
    int N , K;
    int size[MAX_N]  ;
    int opt[MAX_N];
    bool del[MAX_N] ;
    long long  Ans ;
    vector<int>  tnode;
    void Dfs(int u,int fa)
    {
    	tnode.push_back(u);
    	opt[u] = 0;
    	size[u] = 1;
    	Tr(it,edge[u])
    	{
    		int v = it->b;
    		if(!del[v] && v!=fa){
    			Dfs(v , u);
    			opt[u] = max(opt[u],size[v]);
    			size[u] += size[v];	
    		}
    	}
    }
    int Find(int u) // find the centre of gravity
    {
    	Dfs(u,-1);
    	int who = -1 , mx = MAX_N;
    	for(vector<int>::iterator it = tnode.begin(); it != tnode.end(); it++)
    	{
    		opt[*it] = max(opt[*it],size[u]-size[*it]);
    		if(mx > opt[*it]) {
    			mx = opt[*it];
    			who = *it;
    		}
    	}
    	return who;
    }
    vector<pair<int,int> > all , ch[MAX_N];
    void Get_dis(int u,int fa,int len,vector<pair<int,int> > &ch,int sum)
    {
    	ch.push_back(make_pair(sum,len));
    	all.push_back(make_pair(sum,len));
    	Tr(it,edge[u])
    	{
    		if(it->b!=fa && !del[it->b]) {
    			Get_dis(it->b,u,len+it->w,ch,sum+1);
    		}
    	}
    }
    struct BIT{
    	int c[MAX_N];
    	int maxn ;
    	void init(int n) {
    		maxn = n;
    		memset(c,0,sizeof(int)*n);
    	}
    	void insert(int x,int d) {
    		for(x++;x<=maxn;x+=x&-x) c[x] += d;
    	}
    	int sum(int x) {
    		int ans = 0;
    		for(x++;x;x-=x&-x) ans += c[x];
    		return ans;
    	}
    }bit;
    int L , W;
    int cmp(pair<int,int> a, pair<int,int> b) {
    	if(a.second != b.second)return a.second < b.second;
    	return a.first < b.first;
    }
    long long calc(vector<pair<int,int> > d,bool f) //这个函数写挫了,囧
    {
     	long long ans  = 0;
    	int pt = 0 , sz = d.size();
    	int mxd = 0;
    	for(int i = 0; i < sz ; i++) {
    		mxd = max(mxd,d[i].first);
    	}
    	bit.init(mxd+2);
    	sort(d.begin(),d.end(),cmp);
    	int cnt = 0;
    	int j = 0;
    	for(int i = sz - 1 ; i >= 0; i--) {// cnt : 单个点到根满意件条的个数,独单计统出来
    		if(f && d[i].first <= L && d[i].second <= W) cnt++;
    		while(j < sz && d[j].second + d[i].second <= W) {
    			bit.insert(d[j].first,1);
    			j++;
    		}
    	    if(L >= d[i].first){
    			ans += bit.sum(min(mxd,L-d[i].first));
    			if(j > i) if(d[i].first+d[i].first <= L) ans --; // 自己 与 自己不能算点对,要去掉
    		}
    	}
    	ans += cnt * 2;
    	return ans;
    }
    void Solve(int u)
    {
    	tnode.clear();
    	u = Find(u); // the gravity center 
    	all.clear(); // all of the distances
    	int nch = 0; // count of sons 
    	Tr(it,edge[u])
    	{
    		ch[nch].clear(); 
    		if(!del[it->b]) Get_dis(it->b,u,it->w,ch[nch++],1);
    	}	
    
    	Ans += calc(all,true);
    	for(int i = 0; i < nch; i++)  Ans -= calc(ch[i],false);	
    
    	del[u] = true;
    	Tr(it,edge[u])
    		if(!del[it->b])  Solve(it->b);
    }
    int main()
    {
    	int a,b,w;
    	while(scanf("%d%d%d",&N,&L,&W)!=EOF)
    	{
    		 for(int i = 1; i <= N; i++) edge[i].clear(),del[i]=false;
             for(int i = 2; i <= N; i++)
    		 {
    			 scanf("%d%d",&a,&w);
    			 edge[i].push_back(Edge(a,w));
    			 edge[a].push_back(Edge(i,w));
    		 }
    		 Ans = 0;
    		 Solve(1);
    		 printf("%I64d\n",Ans/2);
    	}
    	return 0;
    }

    文章结束给大家分享下程序员的一些笑话语录: 很多所谓的牛人也不过如此,离开了你,微软还是微软,Google还是Google,苹果还是苹果,暴雪还是暴雪,而这些牛人离开了公司,自己什么都不是。

  • 相关阅读:
    利用反馈字段给帝国cms添加留言板功能(图文教程)
    对程序员的不尊重是中国it产业的悲哀。
    网站原创文章被盗用怎么办?
    Vector
    iptables
    spark geoip
    geoip scala api
    matlab解三元二次方程组
    统计一个目录下所有普通文本文件的总行数
    awk多模式匹配
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3040099.html
Copyright © 2011-2022 走看看