import java.util.Scanner;
public class Main {
public static void main(String[] arg) {
Scanner scanner = new Scanner(System.in);
// todo
}
}
NC205711. L2-4缘之空
描述
输入描述
第一行两个正整数 n, q, 表示家谱总人数和询问个数。接下来 n-1 行,每行两个正整数 f, c, 表示 f 是 c 的父/母。()
接下来 q 行,每行两个正整数 u, v, 表示一个询问。()
输出描述
对于每个询问,第一行输出“YES”或者“NO”,表示两个人能否结婚。
第二行输出一个整数,表示两个人的亲缘等级。
示例1
输入:
7 3 1 2 1 3 2 4 2 5 3 6 6 7 1 3 4 6 5 7
输出:
NO 1 NO 4 YES 5
C++14(g++5.4) 解法, 执行用时: 509ms, 内存消耗: 2012K, 提交时间: 2020-05-03 15:43:28
#include<bits/stdc++.h>#define IO ios::sync_with_stdio(false), cin.tie(0)#define INF 0x3f3f3f3ftypedef long long ll;using namespace std;int n,m;int f[100005];int dep[100005];int dfs(int x){if(dep[x]!=0||f[x]==0)return dep[x];else return dep[x]=dfs(f[x])+1;}void init(){cin>>n>>m;int fa,s;memset(f,0,sizeof(f));memset(dep,0,sizeof(dep));for(int i=1;i<n;i++){cin>>fa>>s;f[s]=fa;}for(int i=1;i<=n;i++){if(f[i]&&dep[i]==0){dfs(i);}}// cout<<"---"<<endl;// for(int i=1;i<=n;i++){// cout<<i<<" "<<dep[i]<<endl;// }}int lca(int ta,int tb){while(dep[ta]!=dep[tb]){if(dep[ta]>dep[tb]){ta=f[ta];}else{tb=f[tb];}}while(ta!=tb){ta=f[ta];tb=f[tb];}return ta;}int main(){IO;init();for(int i=0;i<m;i++){int ta,tb;cin>>ta>>tb;int tmp=lca(ta,tb);//cout<<"tmp="<<tmp<<endl;int dis=dep[ta]+dep[tb]-2*dep[tmp];if(dis<=4||ta==tmp||tb==tmp){cout<<"NO"<<endl<<dis<<endl;}else{cout<<"YES"<<endl<<dis<<endl;}}return 0;}/**/
C++ 解法, 执行用时: 747ms, 内存消耗: 7656K, 提交时间: 2022-04-12 20:26:46
#include<bits/stdc++.h>#define ll long longusing namespace std;ll n,q,v[100005],d[100005],f[100005];vector<ll>m[100005];void build(ll now,ll de){v[now]=1;d[now]=de;ll l=m[now].size();for(int i=0;i<l;i++){ll to=m[now][i];if(!v[to]){build(to,de+1);}}}int main() {cin>>n>>q;ll x,y;for(int i=1;i<n;i++){cin>>x>>y;f[y]=x;m[x].push_back(y);}x=1;while(f[x])x=f[x];build(x,1);while(q--){cin>>x>>y;ll ans=0,flag=1;while(d[x]>d[y]){x=f[x];ans++;}while(d[y]>d[x]){y=f[y];ans++;}if(x==y){flag=0;}else{while(x!=y){x=f[x];y=f[y];ans+=2;}if(ans<=4)flag=0;}cout<<(flag==1?"YES":"NO")<<endl<<ans<<endl;}return 0;}