[CF1307F]Cow and Vacation

2024-03-16 23:08
文章标签 cow vacation cf1307f

本文主要是介绍[CF1307F]Cow and Vacation,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Cow and Vacation

题解

挺简单的一道题。

首先,我们考虑将每条边拆成两条边,建一个一个虚点,这样方便我们对 k k k的处理。
因为 k k k不一定为偶数,但我们对每个点单独处理最后再合在一起明显是方便许多的。

考虑拆了边之后先将离关键点 x x x距离不超过 k k k的用并查集连成一个连通块,注意,原来的边的长度时变成了 2 2 2的。
每个连通块中的关键点都是可以互相到达的。
这个过程,我们可以用bfs来实现。
之后,对于每个 a , b a,b a,b的询问,若 d i s ( a , b ) ⩽ 2 k dis(a,b)\leqslant 2k dis(a,b)2k,明显是可以直接判断的。
否则我们就让 a a a b b b k k k步, b b b a a a k k k步,找到它们可以到达哪些关键点。
如果它们能够到达的关键点集合是一样的,它们就一定可以互相到达了。

总时间复杂度 O ( ( n + m ) l o g n ) O\left((n+m)log\,n\right) O((n+m)logn)

源码

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
using namespace std;
#define MAXN 400005
#define lowbit(x) (x&-x)
#define reg register
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int,int> pii;
const int mo=998244353;
const double PI=acos(-1.0);
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){_T f=1;x=0;char s=getchar();while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}x*=f;
}
int n,m,k,r,head[MAXN],tot,fa[MAXN],f[MAXN][25],dep[MAXN];
bool vis[MAXN],imp[MAXN];
struct ming{int id,stp;};queue<ming> q;
struct edge{int to,nxt;}e[MAXN<<1];
void addEdge(int u,int v){e[++tot]=(edge){v,head[u]};head[u]=tot;}
void makeSet(int x){for(int i=1;i<=x;i++)fa[i]=i;}
int findSet(int x){return fa[x]==x?x:fa[x]=findSet(fa[x]);}
void unionSet(int a,int b){int u=findSet(a),v=findSet(b);if(u==v)return ;fa[u]=v;
}
void bfs(){makeSet(2*n-1);while(!q.empty())q.pop();for(int i=1;i<=n;i++)if(imp[i])q.push((ming){i,k}),vis[i]=1;while(!q.empty()){ming t=q.front();q.pop();if(!t.stp)continue;int u=t.id;for(int i=head[u];i;i=e[i].nxt){int v=e[i].to;unionSet(u,v);if(vis[v])continue;vis[v]=1;q.push((ming){v,t.stp-1});}}
}
void dosaka(int u,int fa){f[u][0]=fa;dep[u]=dep[fa]+1;for(int i=1;i<=22;i++)f[u][i]=f[f[u][i-1]][i-1];for(int i=head[u];i;i=e[i].nxt)if(e[i].to!=fa)dosaka(e[i].to,u);
}
int lca(int a,int b){if(dep[a]>dep[b])swap(a,b);for(int i=22;i>=0;i--)if(dep[f[b][i]]>=dep[a])b=f[b][i];if(a==b)return a;for(int i=22;i>=0;i--)if(f[a][i]!=f[b][i])a=f[a][i],b=f[b][i];return f[a][0];
}
int findFa(int u,int k){for(int i=22;i>=0;i--)if(k&(1<<i))u=f[u][i];return u;}
signed main(){read(n);read(k);read(r);for(int i=1;i<n;i++){int u,v;read(u);read(v);addEdge(u,i+n);addEdge(i+n,u);addEdge(v,i+n);addEdge(i+n,v);}for(int i=1,x;i<=r;i++)read(x),imp[x]=1;bfs();dosaka(1,0);read(m);while(m--){int a,b;read(a);read(b);int a_b=lca(a,b),u,v;if(dep[a]+dep[b]-2*dep[a_b]<=2*k){puts("YES");continue;}if(dep[a]-dep[a_b]>=k)u=findFa(a,k);else u=findFa(b,dep[a]+dep[b]-2*dep[a_b]-k);if(dep[b]-dep[a_b]>=k)v=findFa(b,k);else v=findFa(a,dep[a]+dep[b]-2*dep[a_b]-k);if(findSet(u)==findSet(v))puts("YES");else puts("NO");}return 0;
}

谢谢!!!

这篇关于[CF1307F]Cow and Vacation的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/817022

相关文章

【POJ】3660 Cow Contest floyd(可以拓扑排序?)

Cow Contest Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 6925 Accepted: 3792 Description N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating i

BFS —— POJ 3278 Catch That Cow

对应POJ题目:点击打开链接 Catch That Cow Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 54686 Accepted: 17096 Description Farmer John has been informed of the location of a fugitive cow

USACO Section 2.3 Cow Pedigrees

题意: N个节点  深度为K  的正则二叉树  求  树有几种形态 思路: 一开始以为是数学题…  看了byvoid的题解才知道是dp… 每棵树由根节点、左子树、右子树构成  由此得状态转移  树=左子树*右子树 节点数和深度是影响答案的属性  所以令dp[i][j]表示i个节点深度在j以内的树的形态数 深度在j以内的树又两个深度在j-1以内的树和一个根节点构成 设左子树k个节

Codeforces 283. B. Cow Program记忆化搜索

output standard output Farmer John has just given the cows a program to play with! The program contains two integer variables, x and y, and performs the following operations on a sequence a1, a2, ..

【POJ3270】【Cow Sorting】

Cow Sorting Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 6411 Accepted: 2488 Description Farmer John's N (1 ≤ N ≤ 10,000) cows are lined up to be milked in the evening. Each

【POJ3268】【Silver Cow Party】【反向dij】【sizeof失效】

Silver Cow Party Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 15522 Accepted: 7039 Description One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going

POJ 1985 Cow Marathon(树的直径)

题目链接 题意:给出一棵树,求出这个树的直径 解答:任选一点进行dfs,会找到一个最远点s,在以这个最远点s进行dfs,会找到一个最远点是t,那么s-t就是树的直径。 //#include<bits/stdc++.h>#include<cstdio>#include<algorithm>#include<vector>#include<cstring>using namespace

POJ 2184 Cow Exhibition (处理负值的01背包)

【题目链接】:click here~~ 【题意】: 题意:给定n头牛的聪明指数S和幸福指数F,如果存在S的和TS>=0与F的和TF>=0同时成立时, 输出TS与TF的和的最大值sum,否则,输出0。 【思路】:      转化问题,求s和为某个固定值时候最大的f和值,然后遍历这些所有的s和以及对应的f和值,求出总和总和最大的那个。      那么这样就是一个0-1背包问题,可以把s值理解

poj3278--Catch That Cow

Catch That Cow Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 43680 Accepted: 13615 Description Farmer John has been informed of the location of a fugitive cow and wants to catch h

poj3267--The Cow Lexicon(dp:字符串组合)

The Cow Lexicon Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 8211 Accepted: 3864 Description Few know that the cows have their own dictionary with W (1 ≤ W ≤ 600) words, each con