[省选联考 2021 A 卷] 支配
如果了解过支配树是什么,其实这道题会相当简单。
明显建立支配树。
考虑连接 带来的影响。
对于 而言,它的最近支配点会变为 。
考虑哪些点的受支配集会改变。显然是存在 如果 的支配集被改变,那么 才可能会因为 而改变。
考虑如何改变。即,如果存在边 ,那么显然 和 的最近支配点在一条链上。
如果 的最近支配点是 的新的最近支配点的祖先,那 必不可能被影响。否则 的最近支配点就会变得和 的一样。
不会快速建立支配树,但不影响总复杂度,扫一遍 。
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <bitset>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define pii pair <int , int>
#define pll pair <LL , LL>
#define mp make_pair
#define fs first
#define sc second
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
//const int Mxdt=100000;
//static char buf[Mxdt],*p1=buf,*p2=buf;
//#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,Mxdt,stdin),p1==p2)?EOF:*p1++;
template <typename T>
void read(T &x) {
T f=1;x=0;char s=getchar();
while(s<'0'||s>'9') {if(s=='-') f=-1;s=getchar();}
while(s>='0'&&s<='9') {x=(x<<3)+(x<<1)+(s-'0');s=getchar();}
x *= f;
}
template <typename T>
void write(T x , char s='\n') {
if(!x) {putchar('0');putchar(s);return;}
if(x<0) {putchar('-');x=-x;}
T tmp[25]={},t=0;
while(x) tmp[t++]=x%10,x/=10;
while(t-->0) putchar(tmp[t]+'0');
putchar(s);
}
const int MAXN = 3e3 + 5;
int n , m , Q , head[MAXN] , to[MAXN * MAXN] , nxt[MAXN * MAXN] , cnt;
void add(int u , int v) {nxt[++cnt] = head[u];head[u] = cnt;to[cnt] = v;}
int deg[MAXN] , tmpd[MAXN] , f[MAXN][22] , dep[MAXN] , pre[MAXN];
int LCA(int x , int y) {
if(dep[x] < dep[y]) swap(x , y);
for (int i = 20; i >= 0; --i) {
if(dep[f[x][i]] >= dep[y]) x = f[x][i];
if(x == y) return x;
}
for (int i = 20; i >= 0; --i) if(f[x][i] != f[y][i]) {
x = f[x][i];
y = f[y][i];
}
return f[x][0];
}
int ans;
int vis[MAXN];
void dfs(int x , int V) {
vis[x] = 1;
ans ++;
for (int i = head[x]; i; i = nxt[i]) {
int v = to[i];
if(vis[v]) continue;
if(dep[pre[v]] > dep[V]) dfs(v , V);
}
}
void ddfs(int x) {
vis[x] = 1;
for (int i = head[x]; i; i = nxt[i]) {
int v = to[i];
if(vis[v]) continue;
ddfs(v);
}
}
vector <int> G[MAXN];
int main() {
freopen("dominator.in" , "r" , stdin);
freopen("dominator.out" , "w" , stdout);
read(n),read(m),read(Q);
for (int i = 1; i <= m; ++i) {
int u , v;
read(u),read(v);
add(u , v);
}
for (int i = 2; i <= n; ++i) {
G[1].push_back(i),deg[i] ++;
vis[i] = 1;
ddfs(1);
for (int j = 1; j <= n; ++j)
if(!vis[j]) G[i].push_back(j),deg[j] ++;
else vis[j] = 0;
}
queue <int> q;
q.push(1);
while(!q.empty()) {
int x = q.front();
q.pop();
dep[x] = dep[pre[x]] + 1;
f[x][0] = pre[x];
for (int i = 1; i <= 20; ++i) f[x][i] = f[f[x][i - 1]][i - 1];
for (int i = 0; i < (int)G[x].size(); ++i) {
int v = G[x][i];
deg[v] --;
if(!deg[v]) q.push(v) , pre[v] = x;
}
}
while(Q -- > 0) {
int s , t;
read(s),read(t);
int v = LCA(s , t);
ans = 0;
if(dep[v] < dep[pre[t]]) dfs(t , v);
write(ans);
for (int i = 1; i <= n; ++i) vis[i] = 0;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具