[省选联考 2021]支配
支配
题解
支配树板子题。
不过貌似SPFA+bitset有75pts?
首先我们应该很容易想到对原图建一棵支配树出来。
考虑加一条边对于支配树的影响情况。
显然,加一条边只会让一个点的被支配集缩小,即有一个以前能支配点
u
u
u的点
z
z
z在加边后不能够继续支配点
u
u
u。
记添加边
(
x
,
y
)
(x,y)
(x,y),
x
x
x与
y
y
y的lca为
d
d
d。很明显,点
z
z
z一定在
d
d
d与
y
y
y之间。
因为我们添加的到
y
y
y的方法是从
1
−
>
d
−
>
x
−
>
y
1->d->x->y
1−>d−>x−>y,总不可能让原来点1到y路径
1
−
>
d
−
>
y
1->d->y
1−>d−>y外其它点变了吧。显然
1
−
>
d
1->d
1−>d的路径是不可能变的,变的只有可能是
d
−
>
y
d->y
d−>y中的点。
而且同时容易证明在
1
1
1到
d
d
d的路径上所有点的儿子节点也是不可能变的,因为
y
y
y与
u
u
u存在横叉边当且仅当
u
u
u是它们两者lca的儿子,除此之外只存在返祖边。
所以我们可以将
1
−
>
d
1->d
1−>d的路径及与这条路径上的点直接相连的点打上标记,再在原图上从
y
y
y开始跑一道dfs即可,答案就是能访问到的点的数量。
时间复杂度 O ( q n ) O\left(qn\right) O(qn)。
源码
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<time.h>
using namespace std;
#define MAXM 3005
#define lowbit(x) (x&-x)
#define reg register
#define mkpr make_pair
#define fir first
#define sec second
typedef long long LL;
typedef unsigned long long uLL;
typedef unsigned int uint;
typedef pair<int,int> pii;
const int INF=0x7f7f7f7f;
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;
}
struct edge{int to,nxt;};
struct Graph{
int head[MAXM],tot;edge e[MAXM<<1];
void addEdge(int u,int v){e[++tot]=(edge){v,head[u]};head[u]=tot;}
}orG,reG,orD,unD,T;
int n,m,Q,dfn[MAXM],pre[MAXM],idx,father[MAXM],deg[MAXM],siz[MAXM],ans;
int anc[MAXM],minanc[MAXM],semi[MAXM],dep[MAXM],f[MAXM][15];
queue<int> q;bool vis[MAXM];
void dfs(int u,int fa){
pre[dfn[u]=++idx]=u;
for(int i=orG.head[u];i;i=orG.e[i].nxt){
int v=orG.e[i].to;if(dfn[v])continue;
dfs(v,u);father[v]=u;orD.addEdge(u,v);
}
}
int findSet(int x){
if(anc[x]==x)return x;int las=anc[x];anc[x]=findSet(anc[x]);
if(dfn[semi[minanc[x]]]>dfn[semi[minanc[las]]])minanc[x]=minanc[las];
return anc[x];
}
void SpTarjan(){
for(int i=1;i<=n;i++)anc[i]=minanc[i]=semi[i]=i;
for(int i=n;i>1;i--){
int x=pre[i],minn=i;if(!x)continue;
for(int j=reG.head[x];j;j=reG.e[j].nxt){
int v=reG.e[j].to;if(!dfn[v])continue;
if(dfn[v]<dfn[x])minn=min(dfn[v],minn);
else findSet(v),minn=min(dfn[semi[minanc[v]]],minn);
}
semi[x]=pre[minn];anc[x]=father[x];orD.addEdge(semi[x],x);
}
}
int lca(int a,int b){
if(dep[a]<dep[b])swap(a,b);
for(int i=12;i>=0;i--)if(dep[f[a][i]]>=dep[b])a=f[a][i];
if(a==b)return a;
for(int i=12;i>=0;i--)if(f[a][i]^f[b][i])a=f[a][i],b=f[b][i];
return f[a][0];
}
void build(int x){
int res=unD.e[unD.head[x]].to;
for(int i=unD.head[x];i;i=unD.e[i].nxt)res=lca(res,unD.e[i].to);
dep[x]=dep[res]+1;f[x][0]=res;T.addEdge(res,x);
for(int i=1;i<=12;i++)f[x][i]=f[f[x][i-1]][i-1];
}
void sakura(){
while(!q.empty())q.pop();q.push(0);
for(int i=1;i<=n;i++)
for(int j=orD.head[i];j;j=orD.e[j].nxt)
deg[orD.e[j].to]++,unD.addEdge(orD.e[j].to,i);
for(int i=1;i<=n;i++)if(!deg[i])orD.addEdge(0,i),unD.addEdge(i,0),deg[i]++;
while(!q.empty()){
int t=q.front();q.pop();
for(int i=orD.head[t];i;i=orD.e[i].nxt){
int v=orD.e[i].to;deg[v]--;
if(!deg[v])build(v),q.push(v);
}
}
}
void dosaka(int x,int fa){
siz[x]=1;f[x][0]=fa;for(int i=1;i<=12;i++)f[x][i]=f[f[x][i-1]][i-1];
for(int i=T.head[x];i;i=T.e[i].nxt)dosaka(T.e[i].to,x),siz[x]+=siz[T.e[i].to];
}
void dosaka2(int x){
if(!vis[x])vis[x]=1,ans++;
for(int i=orG.head[x];i;i=orG.e[i].nxt)
if(!vis[orG.e[i].to])dosaka2(orG.e[i].to);
}
signed main(){
read(n);read(m);read(Q);
for(int i=1;i<=m;i++){
int u,v;read(u);read(v);
orG.addEdge(u,v);reG.addEdge(v,u);
}
dfs(1,0);SpTarjan();sakura();memset(f,0,sizeof(f));dosaka(1,0);
for(int i=1;i<=Q;i++){
int s,t;read(s);read(t);int s_t=lca(s,t);
if(s_t==t||dep[s_t]==dep[t]-1){puts("0");continue;}
for(int j=1;j<=n;j++)vis[j]=0;ans=0;
while(s_t){
for(int j=T.head[s_t];j;j=T.e[j].nxt)vis[T.e[j].to]=1;
vis[s_t]=1,s_t=f[s_t][0];
}
dosaka2(t);printf("%d\n",ans);
}
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工具