zoukankan      html  css  js  c++  java
  • ●POJ 1741 Tree

    题链:

    http://poj.org/problem?id=1741
    题解:

    树上点分治。
    入门题,不多说了。


    代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #define MAXN 10004
    using namespace std;
    struct EDGE{
    	int ent;
    	int to[MAXN*2],nxt[MAXN*2],val[MAXN*2],head[MAXN];
    	void Reset(){ent=2; memset(head,0,sizeof(head));}
    	void Adde(int u,int v,int w){
    		to[ent]=v; val[ent]=w; nxt[ent]=head[u]; head[u]=ent++;
    		to[ent]=u; val[ent]=w; nxt[ent]=head[v]; head[v]=ent++;
    	}
    }E;
    int N,K;
    long long ANS;
    int size[MAXN];
    bool vis[MAXN];
    void getroot(int u,int dad,int num,int &root,int &rootnum){
    	int maxnum=0; size[u]=0;
    	for(int i=E.head[u];i;i=E.nxt[i]){
    		if(E.to[i]==dad||vis[E.to[i]]) continue;
    		getroot(E.to[i],u,num,root,rootnum);
    		size[u]+=size[E.to[i]];
    		maxnum=max(maxnum,size[E.to[i]]);
    	}
    	size[u]++; maxnum=max(maxnum,num-size[u]);
    	if(maxnum<rootnum) root=u,rootnum=maxnum;
    }
    long long calc(int s,int len){
    	long long ret=0;
    	static int dis[MAXN],A[MAXN],reach[MAXN],rnt,ant;
    	static queue<int>Q;
    	ant=0; rnt++; Q.push(s);
    	dis[s]=len; reach[s]=rnt;
    	while(!Q.empty()){
    		int u=Q.front(); Q.pop(); A[++ant]=dis[u];
    		for(int i=E.head[u];i;i=E.nxt[i]){
    			int v=E.to[i];
    			if(reach[v]==rnt||vis[v]) continue;
    			dis[v]=dis[u]+E.val[i];
    			reach[v]=rnt; Q.push(v);
    		}
    	}
    	sort(A+1,A+ant+1);
    	int l=1,r=ant;
    	while(l<=r){
    		if(A[l]+A[r]>K) r--;
    		else ret+=r-l,l++;
    	}
    	return ret;
    }
    void divide(int u){
    	int root=u,rootnum=size[u];
    	getroot(u,0,size[u],root,rootnum);
    	vis[root]=1;
    	ANS+=calc(root,0);
    	for(int i=E.head[root];i;i=E.nxt[i]) if(!vis[E.to[i]])
    		ANS-=calc(E.to[i],E.val[i]);
    	for(int i=E.head[root];i;i=E.nxt[i]) if(!vis[E.to[i]])
    		divide(E.to[i]);
    }
    void read(int &x){
    	static int sign; static char ch;
    	x=0; sign=1; ch=getchar();
    	while(ch<'0'||'9'<ch){if(ch=='-')sign=-1;ch=getchar();}
    	while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	x=x*sign;
    }
    int main(){
    	while(1){
    		read(N); read(K);
    		if(!N&&!K) break;
    		E.Reset(); ANS=0;
    		memset(vis,0,sizeof(vis));
    		for(int i=1,u,v,w;i<N;i++)
    			read(u),read(v),read(w),E.Adde(u,v,w);
    		size[1]=N; divide(1);
    		printf("%lld
    ",ANS);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    socket套接字通信和粘包问题
    TCP协议
    网络编程
    单例模式
    类的内置方法(魔法方法)
    反射(hasattr和getattr和setattr和delattr)
    isinstance与issubclass
    绑定方法与非绑定方法
    鸭子类型
    类的多态和抽象类
  • 原文地址:https://www.cnblogs.com/zj75211/p/8541904.html
Copyright © 2011-2022 走看看