hdu2586【How far away ?】

[tarjian离线求lca]

hdu2586【How far away ?】

Time Limit: 2000/1000 MS (Java/Others)   Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 13605 Accepted Submission(s): 5101

【Problem Description】There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B"? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path("simple" means you can't visit a place twice) between every two houses. Yout task is to answer all these curious people.

【Input】First line is a single integer T(T<=10), indicating the number of test cases. For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n. Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.

【Output】For each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case. Sample Input23 21 2 103 1 151 22 32 21 2 1001 22 1 Sample Output1025100100Source ECJTU 2009 Spring Contest 

题目大意】:就是tarjian离线求LCA的裸体。。 但是这道题我卡了很久,,原因就是罪恶的HDU,,,他的M不是200,,,只是不止200,我把M也开成40000才过,,,,事实证明,用OJ必须随意开数组,,,kao.

友链:[这个lca讲的不错](http://blog.youkuaiyun.com/hnust_xiehonghao/article/details/9109295)

【代码】

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
#define cle(x) memset(x,0,sizeof(x))
const int N=40010,M=210;
struct ii{
 int to,ne,v;
 ii(int to=0,int ne=0,int v=0):to(to),ne(ne),v(v){ }
}ed[N*2];
struct tt{
 int to,ne;
 tt(int to =0,int ne=0):to(to),ne(ne){ }
}qu[N*2];
int head[N],first[N],num[N],fa[N],ufa[N];
bool vis[N];
inline int readin(){
 int res=0;
 char ch;
 while((ch = getchar())>'9'||ch<'0');
 res=ch-'0';
 while((ch = getchar())>='0'&&ch<='9')
  res=res*10+ch-'0';
 return res;
}
int lca[M],lca_dis[M],dis[N];
int find_fa(int x){return (x==ufa[x])?x:ufa[x]=find_fa(ufa[x]);}//查找的是ufa,,不是fa,,!!!
void tarjian(int u,int w){
 vis[u]=true;
 dis[u]=w;
 ufa[u]=u;
 for(int i = head[u];i;i=ed[i].ne){
  int v=ed[i].to;
  if(fa[u]==v)continue;
  fa[v]=u;
  tarjian(v,w+ed[i].v);
  ufa[v]=u;
 }
 for(int i = first[u];i;i=qu[i].ne){
  int v=qu[i].to;
  if(!vis[v])continue;
  int p=num[i];
  lca[p]=find_fa(v);
  lca_dis[p]=dis[u]+dis[v]-dis[lca[p]]*2;
 }
}
int main(){
 freopen("hdu.in","r",stdin);
 freopen("hdu.out","w",stdout);
 int T=readin();
 for(int o = 1; o<= T; o++){
  int n=readin(),m=readin();
  cle(ed),cle(qu),cle(head),cle(first),cle(num),cle(lca),cle(lca_dis),cle(fa),cle(ufa);
  cle(dis),cle(vis);//数组记得清空完全。。
  for(int i=1;i<=n-1;i++){
   int x=readin(),y=readin(),z=readin();
   ed[i*2-1]=ii(y,head[x],z);
   head[x]=i*2-1;
   ed[i*2]=ii(x,head[y],z);
   head[y]=i*2;
  }
  for(int i=1; i<=m;i++){
   int x=readin(),y=readin();
   qu[i*2-1]=tt(y,first[x]);
   first[x]=i*2-1;
   qu[i*2]=tt(x,first[y]);
   first[y]=i*2;
   num[i*2-1]=num[i*2]=i;//存储是第几个询问,必须双向。
  }
  fa[1]=1;//这个并不知道是否有问题,,,记得实验一次!!!!
  tarjian(1,0);
  for(int i=1;i<=m;i++)
   printf("%d\n",lca_dis[i]);
 }
}

### HDU OJ 2073 Problem Description and Solution The problem **HDU OJ 2073** titled *"Find the closest prime number"* requires finding the nearest prime number to a given integer \( N \). If two primes are equally close, output the smaller one. #### Input Specification Multiple test cases exist. Each test case contains an integer \( N \), where \( 1 \leq N \leq 2^{31} - 1 \). #### Output Specification For each input value \( N \), output its closest prime number on a new line. --- To solve this problem efficiently, we can use the following approach: 1. **Prime Checking Function**: Implement a function `is_prime(x)` to check whether a number \( x \) is prime by testing divisibility up to \( \sqrt{x} \)[^4]. ```python import math def is_prime(n): if n < 2: return False for i in range(2, int(math.sqrt(n)) + 1): if n % i == 0: return False return True ``` 2. **Search Strategy**: Starting from \( N \), search both upwards (\( N+1, N+2, ... \)) and downwards (\( N-1, N-2, ... \))[^5]. Stop when the first prime is found. ```python def find_closest_prime(N): lower = upper = N while True: if is_prime(lower): return lower elif is_prime(upper): return upper lower -= 1 upper += 1 ``` 3. **Handling Multiple Test Cases**: Read multiple inputs until EOF (End of File) or as specified in the contest environment[^6]. ```python import sys lines = sys.stdin.read().splitlines() results = [] for num_str in lines: N = int(num_str.strip()) result = find_closest_prime(N) results.append(result) print("\n".join(map(str, results))) ``` This algorithm ensures correctness because it systematically checks numbers around \( N \) using efficient primality tests. The time complexity depends heavily on how far away the next prime lies but remains manageable within reasonable bounds due to optimizations like square root checking during primality verification. --- ### Example Walkthrough Given \( N = 10 \): - Check downward: \( 9 \rightarrow \text{not prime}, 8 \rightarrow \text{not prime}, ..., 7 \rightarrow \text{prime!} \). - Return \( 7 \) since no closer prime exists above \( 10 \). If another example were provided with \( N = 15 \): - Check upward: \( 16 \rightarrow \text{not prime}, 17 \rightarrow \text{prime!} \). - Since \( |17 - 15| = 2 \) matches any potential downward candidate's distance, choose the smallest among them—here still \( 17 \). Thus, outputs align accordingly based upon proximity rules defined earlier. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值