关于 AT G 题
  • 板块学术版
  • 楼主rainygame
  • 当前回复6
  • 已保存回复6
  • 发布时间2023/9/2 21:49
  • 上次更新2023/11/2 23:46:29
查看原帖
关于 AT G 题
804607
rainygame楼主2023/9/2 21:49

当 A→B→CA\rightarrow B \rightarrow C 有一条简单路径时,需要满足 C→BC \rightarrow B 中 AA 不是必须经过的点,且 A→BA \rightarrow B 中 CC 不是必须经过的点。

因此考虑将图转化为圆方树后树链剖分,枚举 A→BA\rightarrow B 的树上路径中是否有 CC。再枚举 C→BC\rightarrow B 上是否有 AA。如果都没有就输出 Yes,否则输出 No。

代码如下:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define MAXN 200001

int n, m, q, u, v, cnt, ssum, res, a, b, c, lca;
int id[MAXN<<1];
int dfn[MAXN], low[MAXN];
int dep[MAXN<<1], fa[MAXN<<1], top[MAXN<<1], siz[MAXN<<1], son[MAXN<<1];
vector<int> e[MAXN], t[MAXN<<1];
stack<int> st;

void tarjan(int x){
	dfn[x] = low[x] = ++cnt;
	st.push(x);
	for (auto i: e[x]){
		if (!dfn[i]){
			tarjan(i);
			low[x] = min(low[x], low[i]);
			if (low[i] == dfn[x]){
				++ssum;
				t[ssum].push_back(x);
				t[x].push_back(ssum);
				while (st.top() != i){
					t[st.top()].push_back(ssum);
					t[ssum].push_back(st.top());
					st.pop();
				}
				t[ssum].push_back(i);
				t[i].push_back(ssum);
				st.pop();
			}
		}else low[x] = min(low[x], dfn[i]);
	}
}

void dfs1(int x, int f){
	fa[x] = f;
	dep[x] = dep[f] + 1;
	siz[x] = 1;
	for (auto i: t[x]){
		if (i != f){
			dfs1(i, x);
			siz[x] += siz[i];
			if (siz[son[x]] < siz[i]) son[x] = i;
		}
	}
}

void dfs2(int x, int tp){
	top[x] = tp;
	if (!son[x]) return;
	dfs2(son[x], tp);
	for (auto i: t[x]){
		if (i != fa[x] && i != son[x]) dfs2(i, i);
	}
}

int LCA(int x, int y){
	while (top[x] != top[y]){
		if (dep[top[x]] < dep[top[y]]) swap(x, y);
		x = fa[top[x]];
	}
	if (dep[x] < dep[y]) return x;
	return y;
}

void f(int a, int b, int c){
	lca = LCA(b, c);
	while (c != lca){
		if (c == a){
			cout << "No";
			exit(0);
		}
		c = fa[c];
	}
	if (c == a){
		cout << "No";
		exit(0);
	}
	while (b != lca){
		if (b == a){
			cout << "No";
			exit(0);
		}
		b = fa[b];
	}
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
    cin >> n >> m >> a >> b >> c;
    while (m--){
    	cin >> u >> v;
    	e[u].push_back(v);
    	e[v].push_back(u);
	}
	
	ssum = n;
	tarjan(1);
	dfs1(1, 0);
	dfs2(1, 1);
	
	f(a, b, c);
	f(c, b, a);
	cout << "Yes";

    return 0;
}
2023/9/2 21:49
加载中...