zoukankan      html  css  js  c++  java
  • 【poj2114】 Boatherds

    http://poj.org/problem?id=2114 (题目链接)

    题意

      给出一棵树,问是否存在两点间的距离为K。

    Solution

      点分治嘛,跟poj1741差不多。。

      然而为什么我调了一个下午。。map真是坑死了,各种TLE,以后再也不写了。

    代码

    // poj2114
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<set>
    #define LL long long
    #define MOD 100000000
    #define inf 2147483640
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    
    set<int> s;
    const int maxn=10010;
    struct edge {int to,next,w;}e[maxn<<1];
    int head[maxn],size[maxn],deep[maxn],d[maxn],f[maxn],vis[maxn],ans[maxn],q[maxn];
    int m,sum,rt,n,cnt;
    
    void link(int u,int v,int w) {
    	e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w;
    	e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt;e[cnt].w=w;
    }
    void Init() {
    	cnt=0;f[0]=inf;
    	for (int i=1;i<=n;i++) head[i]=f[i]=vis[i]=0;
    }
    void calroot(int x,int fa) {
    	size[x]=1;f[x]=0;
    	for (int i=head[x];i;i=e[i].next)
    		if (!vis[e[i].to] && e[i].to!=fa) {
    			calroot(e[i].to,x);
    			size[x]+=size[e[i].to];
    			f[x]=max(f[x],size[e[i].to]);
    		}
    	f[x]=max(f[x],sum-size[x]);
    	if (f[x]<f[rt]) rt=x;
    }
    void caldeep(int x,int fa) {
    	deep[++deep[0]]=d[x];
    	for (int i=head[x];i;i=e[i].next)
    		if (!vis[e[i].to] && e[i].to!=fa) {
    			d[e[i].to]=d[x]+e[i].w;
    			caldeep(e[i].to,x);
    		}
    }
    void cal(int x,int now) {
    	d[x]=now;deep[0]=0;
    	caldeep(x,0);
    	for (int i=1;i<=m;i++) if (!ans[i]) {
    			for (int j=1;j<=deep[0];j++) if (q[i]>=deep[j]) {
    					if (q[i]-deep[j]==0) ans[i]=1;
    					else if (s.count(q[i]-deep[j])) ans[i]=1;
    				}
    		}
    	for (int i=1;i<=deep[0];i++) s.insert(deep[i]);
    }
    void solve(int x) {
    	vis[x]=1;s.clear();
    	for (int i=head[x];i;i=e[i].next) if (!vis[e[i].to]) cal(e[i].to,e[i].w);
    	for (int i=head[x];i;i=e[i].next) if (!vis[e[i].to]) {
    		sum=size[e[i].to];
    		rt=0;calroot(e[i].to,x);
    		solve(rt);
    	}
    }
    int main() {
    	while (scanf("%d",&n)!=EOF && n) {
    		Init();
    		for (int d,c,i=1;i<=n;i++)
    			while (scanf("%d",&d)!=EOF && d) {
    				scanf("%d",&c);
    				link(i,d,c);
    			}
    		m=0;int x;
    		while (scanf("%d",&x)!=EOF && x) q[++m]=x;
    		for (int i=1;i<=m;i++) ans[i]=0;
    		rt=0;sum=n;
    		calroot(1,0);
    		solve(rt);
    		for (int i=1;i<=m;i++) {
    			if (ans[i]) printf("AYE
    ");
    			else printf("NAY
    ");
    		}
    		printf(".
    ");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    sed命令
    awk命令
    let命令
    首先看一下友晶DE-SOC开发板的user manual
    嵌入式FIFO核的调用
    嵌入式ROM核的调用
    用嵌入式块RAM IP核配置一个双口RAM
    如何利用Visio设计一个系统的结构图
    uart通讯协议
    按键消抖试验及一个数码管电子时钟的设计
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/5932525.html
Copyright © 2011-2022 走看看