1.相遇
(railway.cpp/c/pas)
时间限制:1s
内存限制:256MB
【问题描述】
已知我国有 n 座城市,这些城市通过 n-1 条高铁相连。且任意两个城市联通。
小 A 想从 x1 号城市出发,到 y1 号城市,小 B 想从 x2 号城市出发,到 y2 号
城市,问他们是否可能在路途中相遇(出现在同一城市)
你需要回答 m 次这样的问题。
【输入】
输入文件名为 railway.in。
第一行一个数 T(<=10),表示数据组数
对于每一组数据:
第一行两个数 n,m(1<=n,m<=100,000)
第 2~n 行,每行两个数 x,y 表示有一条铁路连接城市 x 和 y
接下来 m 行每行四个数,分别表示 x1,y1,x2,y2,表示一次询问
【输出】
输出文件名为 railway.out。
对于每次询问输出 YES 或 NO
【输入输出样例】
| railway.in | railway.out |
| 1 4 2 1 2 2 3 3 4 1 2 3 4 1 4 2 3 |
NO YES |
【数据说明】
对于 30%的数据,n,m<=100
对于 60%的数据,n,m<=1000
对于 100%的数据,n,m<=100,000
太没意思了,树上路径求交,这已经是我近三个月做的第三次了==上次计蒜客刚考过==
考察:LCA+ 分类情况讨论
预计得分:100分
实际得分:100分
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<queue> 5 #include<cmath> 6 #define maxn 100090 7 8 using namespace std; 9 10 int n,m,T,tot,t; 11 int d[maxn],head[maxn],f[maxn][20]; 12 struct node{ 13 int to,next; 14 }edge[maxn*2]; 15 16 void add(int x,int y) 17 { 18 edge[++tot].to=y; 19 edge[tot].next=head[x]; 20 head[x]=tot; 21 } 22 23 void init() 24 { 25 queue<int>q; 26 q.push(1);d[1]=1; 27 while(!q.empty()) 28 { 29 int u=q.front();q.pop(); 30 for(int i=head[u];i;i=edge[i].next) 31 { 32 int v=edge[i].to; 33 if(d[v]) continue; 34 d[v]=d[u]+1; 35 f[v][0]=u; 36 for(int j=1;j<=t;j++) 37 f[v][j]=f[f[v][j-1]][j-1]; 38 q.push(v); 39 } 40 } 41 } 42 43 int lca(int x,int y) 44 { 45 if(d[x]>d[y]) swap(x,y); 46 for(int i=t;i>=0;i--) 47 if(d[f[y][i]]>=d[x]) y=f[y][i]; 48 if(x==y) return x; 49 for(int i=t;i>=0;i--) 50 if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; 51 return f[x][0]; 52 } 53 54 void Clear() 55 { 56 tot=0; 57 memset(head,0,sizeof(head)); 58 memset(d,0,sizeof(d)); 59 memset(f,0,sizeof(f)); 60 } 61 62 int main() 63 { 64 freopen("railway.in","r",stdin); 65 freopen("railway.out","w",stdout); 66 scanf("%d",&T); 67 while(T--) 68 { 69 scanf("%d%d",&n,&m); 70 t=log2(n)+1; 71 for(int i=1;i<=n-1;i++) 72 { 73 int x=0,y=0; 74 scanf("%d%d",&x,&y); 75 add(x,y),add(y,x); 76 } 77 init(); 78 for(int i=1;i<=m;i++) 79 { 80 int a=0,b=0,c=0,e=0; 81 scanf("%d%d%d%d",&a,&b,&c,&e); 82 int p=lca(a,b); 83 int q=lca(c,e); 84 if(p==q) {printf("YES\n");continue;} 85 else if(d[p]>d[q]) 86 { 87 if(lca(p,c)==p||lca(p,e)==p) printf("YES\n"); 88 else printf("NO\n"); 89 } 90 else 91 { 92 if(lca(q,a)==q||lca(q,b)==q) printf("YES\n"); 93 else printf("NO\n"); 94 } 95 } 96 Clear(); 97 } 98 return 0; 99 }