月赛 2C
  • 板块学术版
  • 楼主Coffee_zzz/xin
  • 当前回复15
  • 已保存回复15
  • 发布时间2023/8/13 18:05
  • 上次更新2023/11/3 04:03:29
查看原帖
月赛 2C
744687
Coffee_zzz/xin楼主2023/8/13 18:05

写了一个 分层图 + LCA + 拓扑 的做法,想问问有么有更优的。

顺便贴一下我的代码。

const int N=2e5+5,L=18;
int x[N],y[N],fr[N<<1],to[N<<1],nxt[N<<1],cnt=1,head[N],fa[N],dep[N],f[N][L];
bool vis[N<<1];
vector <int> col[N];
vector <int> son[N];
vector <int> poi[N];
map <pair<int,int>,int> mm;
int deg[N];
void add(int u,int v){
	to[++cnt]=v;
	fr[cnt]=u;
	nxt[cnt]=head[u];
	head[u]=cnt;
}
void init(int u){
	dep[u]=dep[fa[u]]+1;
	f[u][0]=fa[u];
	for(int i=1;i<L;i++) f[u][i]=f[f[u][i-1]][i-1];
	for(int i=0;i<son[u].size();i++){
		int v=son[u][i];
		init(v);
	}
}
void lca(int &x,int &y){
	if(fa[x]==fa[y]) return;
	for(int i=L-1;i>=0;i--) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
}
void dfs(int u){
	for(int i=head[u];i;i=nxt[i]){
		int v=to[i];
		if(dep[v]==dep[u]-1&&v!=fa[u]){
			int x=fa[u],y=v;
			lca(x,y);
			poi[x].push_back(y);
			deg[y]++;
		}
	}
	for(int i=0;i<son[u].size();i++) dfs(son[u][i]);
}
void bfs(int d){
	if(col[d].size()==0) return;
	queue <int> q;
	for(int i=0;i<col[d].size();i++){
		int u=col[d][i];
		if(deg[u]==0) q.push(u);
	}
	while(!q.empty()){
		int u=q.front();
		q.pop();
		cout<<u<<' '<<fa[u]<<endl;
		mm[{max(u,fa[u]),min(u,fa[u])}]--;
		for(int i=0;i<poi[u].size();i++){
			int v=poi[u][i];
			deg[v]--;
			if(deg[v]==0) q.push(v);
		}
	}
	bfs(d+1);
}
void solve(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>x[i]>>y[i];
		add(x[i],y[i]),add(y[i],x[i]);
		mm[{max(x[i],y[i]),min(x[i],y[i])}]++;
	}
	for(int i=1;i<=n;i++) cin>>fa[i],son[fa[i]].push_back(i);
	init(1);
	for(int i=1;i<=n;i++) col[dep[i]].push_back(i);
	dfs(1);
	bfs(2);
	for(int i=2;i<=cnt;i+=2) if(mm[{max(to[i],fr[i]),min(to[i],fr[i])}]) cout<<to[i]<<' '<<fr[i]<<endl,mm[{max(to[i],fr[i]),min(to[i],fr[i])}]--;	
}
2023/8/13 18:05
加载中...