有向图上支配树
Posted wang9897
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有向图上支配树相关的知识,希望对你有一定的参考价值。
按照论文的做法 引入半支配点 然后用处理DAG图的做法去处理支配树即可 存模板
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <stack> #include <queue> #include <cmath> #include <set> #include <map> #define mp make_pair #define pb push_back #define pii pair<int,int> #define link(x) for(edge *j=h[x];j;j=j->next) #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,r,l) for(int i=r;i>=l;i--) const int MAXN=3e5+10; const double eps=1e-8; #define ll long long using namespace std; struct edge{int t;edge*next;}e[MAXN<<1],*h[MAXN],*o=e; void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;} ll read(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-‘0‘,ch=getchar(); return x*f; } bool vis[MAXN]; int p[MAXN],tot,fp[MAXN],Dep[MAXN]; int fa[MAXN],du[MAXN]; vector<int>vec[MAXN],v1[MAXN],v2[MAXN]; void dfs(int x,int pre,int deep){ p[x]=++tot;fp[p[x]]=x;fa[x]=pre;Dep[x]=deep+1; link(x){ if(vis[j->t])continue; vis[j->t]=1;v1[x].pb(j->t);du[j->t]++,v2[j->t].pb(x); dfs(j->t,x,deep+1); } } int Min(int x,int y){ if(Dep[x]<Dep[y])return x; return y; } int f[MAXN],key[MAXN],n; int find1(int x){ if(x==f[x])return x; int y=find1(f[x]); key[x]=Min(key[x],key[f[x]]); f[x]=y; return y; } queue<int>que; int F[MAXN][21],dep[MAXN]; int Lca(int x,int y){ if(dep[x]<dep[y])swap(x,y); int tmp=dep[x]-dep[y]; for(int i=0;i<=20;i++)if(tmp&(1<<i))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]; } void Topu(int s){ F[s][0]=0;dep[s]=1;que.push(s); while(!que.empty()){ int x=que.front();que.pop(); for(int i=0;i<v1[x].size();i++){ int y=v1[x][i];du[y]--; if(!du[y]){ que.push(y);int lca=x; for(int j=0;j<v2[y].size();j++)lca=Lca(lca,v2[y][j]); F[y][0]=lca;dep[y]=dep[lca]+1;add(lca,y); inc(j,1,20)F[y][j]=F[F[y][j-1]][j-1]; } } } } int sz[MAXN]; vector<int>ans; void dfs1(int x,int pre){ link(x){ dfs1(j->t,x);sz[x]+=sz[j->t]; } } int main(){ n=read();int m=read();int s=read(); inc(i,1,n+m)Dep[i]=n+m+1; int cnt=n; int x,y; inc(i,1,m)x=read(),y=read(),cnt++,add(x,cnt),add(cnt,y),vec[y].pb(cnt),vec[cnt].pb(x); inc(i,1,cnt)f[i]=key[i]=i; vis[s]=1;dfs(s,0,0); dec(i,tot,1){ y=fp[i]; for(int j=0;j<vec[fp[i]].size();j++){ x=vec[fp[i]][j]; find1(x); key[y]=Min(key[y],key[x]); } if(fa[y])f[y]=fa[y],v1[key[y]].pb(y),du[y]++,v2[y].pb(key[y]); } memset(h,0,sizeof(h));o=e; Topu(s); inc(i,1,n)sz[i]=1; dfs1(s,0); inc(i,1,m)if(!sz[i+n])ans.pb(i); printf("%d ",ans.size()); for(int i=0;i<ans.size();i++)printf("%d ",ans[i]); printf(" "); }
以上是关于有向图上支配树的主要内容,如果未能解决你的问题,请参考以下文章