MnZn 求时间复杂度分析
  • 板块学术版
  • 楼主Laisira
  • 当前回复3
  • 已保存回复3
  • 发布时间2024/9/27 15:29
  • 上次更新2024/9/27 18:03:16
查看原帖
MnZn 求时间复杂度分析
983519
Laisira楼主2024/9/27 15:29

一个离线维护加边后边双联通的玩意。

图不保证联通。

#include<bits/stdc++.h>
#define Maxn 2000005 
using namespace std;
struct egde {
	int u,v,w; 
	bool operator<(const egde&is) 
	const {return w > is.w;} 
} e[Maxn];
struct Query {
	int id,u,v;
} Q[Maxn];
int find(int x,int *f) {
	return f[x] == x?x:f[x] = find(f[x],f);
}
int f[Maxn],g[Maxn];
vector<int> q[Maxn];
int dep[Maxn],F[Maxn];
void dfs(int x,int fa) {
	F[x] = fa;
	dep[x] = dep[fa] + 1;
	for(int u:q[x]) 
	if(u != fa) dfs(u,x);
}
bool ans[Maxn];
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,m,t,tid;
	cin>>n>>m>>t>>tid;
	for(int i=1;i<=m;i++)
		cin>>e[i].u>>e[i].v,e[i].w = t+1;
	for(int i=1;i<=t;i++) {
		cin>>Q[i].id;
		if(Q[i].id == 1)
			cin>>Q[i].u,e[Q[i].u].w = i;
		else cin>>Q[i].u>>Q[i].v;
	}
	for(int i=1;i<=n;i++)
		f[i] = g[i] = i;
	sort(e+1,e+1+m);
	for(int i=1;i<=m;i++) {
		int u = e[i].u,v = e[i].v;
		int fu = find(u,f),fv = find(v,f);
		if(fu != fv) {
			q[u].push_back(v);
			q[v].push_back(u);
			f[fu] = fv;
			e[i].w = -1;
		}
	}
	for(int i=1;i<=n;i++)
		if(!dep[i])dfs(i,i);
	int p = t;
	while(Q[p].id == 1)p --;
	for(int i=1;i<=m;i++) {
		if(e[i].w == -1)continue;
		while(p > 0&&p > e[i].w) {
			if(find(Q[p].u,g) == find(Q[p].v,g))
				ans[p] = true; p --;
			while(p > 0&&Q[p].id == 1)p --;
		}
		int u = find(e[i].u,g),v = find(e[i].v,g),opt = u;
		while(u != v) {
			if(dep[u] > dep[v])swap(u,v);
			g[v] = opt;
			v = find(F[v],g);
		} F[opt] = F[u],g[u] = opt;
	}
	while(p > 0) {
		if(find(Q[p].u,g) == find(Q[p].v,g))
			ans[p] = true; p --;
		while(p > 0&&Q[p].id == 1)p --;
	}
	for(int i=1;i<=t;i++)
		if(ans[i])cout<<"YES\n";
		else if(Q[i].id == 2)
			cout<<"NO\n";
	return 0;
 }
2024/9/27 15:29
加载中...