首页 > 代码库 > poj2114 Boatherds
poj2114 Boatherds
Description
Boatherds Inc. is a sailing company operating in the country of Trabantustan and offering boat trips on Trabantian rivers. All the rivers originate somewhere in the mountains and on their way down to the lowlands they gradually join and finally the single resulting river flows to the sea. Moreover, the Trabantian villages are exactly at the rivers‘ springs, junctions and at the mouth of the largest river. Please note that more than 2 rivers can join at a junction. However, the rivers always form a tree (with villages as vertices).
The pricing policy of the Boatherds is very simple: each segment of each river between two villages is assigned a price (the price is same in both directions), so if a tourist requests a journey between any two villages, the ticket office clerks just add the prices of the segments along the only path between the villages.
One day, a very strange tourist appeared. She told the clerks that she returns to her country on the next day and she wants to spend all the remaining money on a boat trip, so they should find a route with exactly this cost. Being just poor (ahem) businessmen, they have asked the Abacus Calculator Makers for help.
You are given a description of the river network with costs of river segments and a sequence of integers x1,..., xk. For each xi, you should determine if there is a pair of cities (a, b) in the river network such that the cost of the trip between a and b is exactly xi.
The pricing policy of the Boatherds is very simple: each segment of each river between two villages is assigned a price (the price is same in both directions), so if a tourist requests a journey between any two villages, the ticket office clerks just add the prices of the segments along the only path between the villages.
One day, a very strange tourist appeared. She told the clerks that she returns to her country on the next day and she wants to spend all the remaining money on a boat trip, so they should find a route with exactly this cost. Being just poor (ahem) businessmen, they have asked the Abacus Calculator Makers for help.
You are given a description of the river network with costs of river segments and a sequence of integers x1,..., xk. For each xi, you should determine if there is a pair of cities (a, b) in the river network such that the cost of the trip between a and b is exactly xi.
Input
The input consists of several instances. Each instance is described by (in the following order):
The whole input is ended by a single line containing the number 0.
- A single line containing a single integer: the number of villages N (1 <= N <= 10 000).
- N lines describing the villages. The i-th of these lines (1 <= i <= N) describes the village with number i. It contains space separated integers d1, c1, d2, c2, , dki, cki, 0. The dj‘s are numbers of villages from which the rivers flow directly to the village i (with no other villages in between), each cj is the price of the journey between villages i and dj. Moreover, 2 <= dj <= N and 0 <= cj <= 1 000. Village 1 always corresponds to the mouth of the largest river, therefore no di can ever be equal to 1.
- M <= 100 lines describing the queries. The i-th of these lines corresponds to the i-th query and contains a single integer xi (1 <= xi <= 10 000 000).
- The instance is finished by a single line containing the number 0.
The whole input is ended by a single line containing the number 0.
Output
For each instance you should produce a sequence of M lines (where M is the number of queries in the particular instance). The i-th of these lines contains the word "AYE" if there exists a pair of cities in the river network which is connected by a path of cost xi, or the word "NAY" otherwise.
Output for each instance must be followed by a single line containing just the dot character.
Output for each instance must be followed by a single line containing just the dot character.
Sample Input
62 5 3 7 4 1 005 2 6 3 000018131400
Sample Output
AYEAYENAYAYE.
询问树上有没有长度为k的路径……对于询问一个一个点分治……反正n才10000m才100
输入好蛋疼……第一行n,接下来n行,每两个数ci、di,表示i和ci有长度为di的边,以0结束。接下来输入询问,以0结束。又有多组数据,以0结束
#include<cstdio>#include<iostream>#include<cstring>#define LL long long#define N 40010#define mod 10207using namespace std;inline LL read(){ LL x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f;}struct edge{int to,next,v;}e[2*N];struct hashing{int v,next;}hash[2*N];int he[N],head[N];int f[N],son[N],s[N],d[N],query[N];bool vis[N],ok[N];int n,m,cnt,tot,root,sum,len,ans;inline void ins(int u,int v,int w){ e[++cnt].to=v; e[cnt].v=w; e[cnt].next=head[u]; head[u]=cnt;}inline void insert(int u,int v,int w){ ins(u,v,w); ins(v,u,w);}inline void inh(int u){ int w=u%mod+132; hash[++tot].v=u; hash[tot].next=he[w]; he[w]=tot;}inline bool fnd(int u){ if (u<0)return 0; int w=u%mod+132; for (int i=he[w];i;i=hash[i].next) if (u==hash[i].v)return 1; return 0;}inline void getroot(int x,int fa){ son[x]=1;f[x]=0; for (int i=head[x];i;i=e[i].next) if (fa!=e[i].to&&!vis[e[i].to]) { getroot(e[i].to,x); son[x]+=son[e[i].to]; f[x]=max(f[x],son[e[i].to]); } f[x]=max(f[x],sum-son[x]); if (f[x]<f[root])root=x;}inline void dfs(int x,int fa){ s[++len]=d[x]; for (int i=head[x];i;i=e[i].next) if (!vis[e[i].to]&&fa!=e[i].to) { d[e[i].to]=d[x]+e[i].v; dfs(e[i].to,x); }}inline void solve(int x){ vis[x]=1;tot=0; memset(he,0,sizeof(he));inh(0); for (int i=head[x];i;i=e[i].next) if (!vis[e[i].to]) { len=0; d[e[i].to]=e[i].v; dfs(e[i].to,0); for (int j=1;j<=m;j++) { if (ok[j])continue; for (int k=1;k<=len;k++) if (fnd(query[j]-s[k])) { ok[j]=1; break; } } for (int j=1;j<=len;j++)inh(s[j]); } for (int i=head[x];i;i=e[i].next) if (!vis[e[i].to]) { sum=son[e[i].to]; root=0; getroot(e[i].to,0); solve(root); }}inline void work(){ memset(head,0,sizeof(head)); memset(vis,0,sizeof(vis)); memset(ok,0,sizeof(ok)); cnt=ans=0; for(int i=1;i<=n;i++) { int x=read(),y; while (x) { y=read(); insert(i,x,y); x=read(); } } m=0; int xx=read(); while (xx) { query[++m]=xx; xx=read(); } f[0]=n+1;sum=n;root=0; getroot(1,0); solve(root); for (int i=1;i<=m;i++) if (ok[i])printf("AYE\n");else printf("NAY\n"); printf(".\n");}int main(){ while (~scanf("%d",&n)&&n)work();}
poj2114 Boatherds
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。