csp-s analog test 51 (b) attack, tree Interpretations

Questions surface: https://www.cnblogs.com/Juve/articles/11598286.html

attack:

Dominator tree bare title?

What is a dominant tree look:

Question: We have a directed graph (ring that may have), set a node as a starting point s. Now we ask: starting from the starting point s, to a point p all paths must go through the X-point what { p }.

In other words, delete X { P } to any point in the X PI and its edges into the edge, so that s will not reach p.

For this problem, the construction of the dominant tree on it

Specific steps:

We bfs to achieve in the new tree, a node x to be able to connect to all lca its point on the original in a new tree

According to this idea, we use the topology, the new update of its parent node in the tree while subtracting a point of penetration of

If it becomes 0 degree, then the multiplication with lca way to add it to a new drawing

Built out of the tree, then the answer is to ask each lca lca all inquiries nodes in the new tree

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define re register
using namespace std;
const int MAXN=5e4+5;
const int MAXM=1e5+5;
int n,m,Q,k,ans=0,du[MAXN];
int to[MAXM<<1],nxt[MAXM<<1],pre[MAXN],cnt=0;
inline void add(re int u,re int v){
	++cnt,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt;
}
int f[MAXN][22],deep[MAXN];
int LCA(int x,int y){
	if(deep[x]<deep[y]) swap(x,y);
	int k=deep[x]-deep[y];
	for(int i=0;i<=20;i++)
		if((1<<i)&k)
			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];
}
queue<int>q;
void bfs(int st){
	deep[st]=1;
	q.push(st);
	while(!q.empty()){
		int x=q.front();
		q.pop();
		for(int i=pre[x];i;i=nxt[i]){
			int y=to[i];
			if(!f[y][0]) f[y][0]=x;
			else f[y][0]=LCA(f[y][0],x);
			f[y][0]=f[y][0];
			deep[y]=deep[f[y][0]]+1;
			--du[y];
			if(!du[y]){
				q.push(y);
				for(int j=0;j<=20;++j){
					if(f[y][j-1]) f[y][j]=f[f[y][j-1]][j-1];
				}
			}
		}
	}
}
signed main(){
	scanf("%d%d%d",&n,&m,&Q);
	for(int i=1,u,v;i<=m;++i){
		scanf("%d%d",&u,&v);
		add(u,v);++du[v];
	}
	bfs(1);
	while(Q--){
		scanf("%d",&k);
		scanf("%d",&ans);
		for(int i=1,vi;i<k;++i){
			scanf("%d",&vi);
			ans=LCA(ans,vi);
		}
		printf("%d\n",deep[ans]);
	}
	return 0;
}

tree:

Simple tree dp?

Probability is teasing you

Set size [x] denotes the subtree size of x, DP [x] represents the first time to a desired number of times x, then:

$dp[x]=dp[fa]+2*(n-size[x])+1$

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int MAXN=1e5+5;
int n;
int to[MAXN<<1],nxt[MAXN<<1],pre[MAXN],cnt=0;
void add(int u,int v){
	++cnt,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt;
}
int siz[MAXN],dp[MAXN];
void dfs(int x,int fa){
	siz[x]=1;
	for(int i=pre[x];i;i=nxt[i]){
		int y=to[i];
		if(y==fa) continue;
		dfs(y,x);
		siz[x]+=siz[y];
	}
}
void DFS(int x,int fa){
	for(int i=pre[x];i;i=nxt[i]){
		int y=to[i];
		if(y==fa) continue;
		dp[y]=dp[x]+2*(n-siz[y])-1;
		DFS(y,x);
	}
}
signed main(){
	scanf("%lld",&n);
	for(int i=1,u,v;i<n;++i){
		scanf("%lld%lld",&u,&v);
		add(u,v),add(v,u);
	}
	dfs(1,0);
	dp[1]=1;
	DFS(1,0);
	for(int i=1;i<=n;++i){
		printf("%0.3lf\n",(double)dp[i]);
	}
	return 0;
}

 

Guess you like

Origin www.cnblogs.com/Juve/p/11598352.html