#1~4 WA 求调
  • 板块P2416 泡芙
  • 楼主fengziyi
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/11/3 21:20
  • 上次更新2023/11/3 23:41:47
查看原帖
#1~4 WA 求调
540226
fengziyi楼主2023/11/3 21:20

Tarjan 边双缩点 + Tarjan 离线 LCA

求一组 hack 数据或错误点。不胜感激。

#include <iostream>
#include <vector>

#define i64 long long
#define endl '\n'
#define qwq puts("fzy qwq ~");
using namespace std;
#define rep(i, l, r) for (int i = (l); i <= (r); ++i)

const int N = 3e5 + 10;
const int M = 3e5 + 10;

int n, m, q;
int dfncnt, dcccnt;
int dfn[N], low[N], dcc[N];
int sum[N], siz[N];
bool b[M << 1];
pair<int, int> qry[N];

struct Graph
{
	struct Edge { int v, w, nxt; };
	Edge e[M << 1]; int h[N], tot = 1;
	inline void add(int u, int v, int w)
	{ e[++tot] = { v, w, h[u] }; h[u] = tot; }
} G, T;

namespace DSU
{
int fa[N];
inline void init(int n) { for (int i = 1; i <= n + 5; ++i) fa[i] = i; }
inline int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
inline void merge(int p, int q) { fa[q] = p; }
}
using namespace DSU;

namespace TarjanLCA
{

struct QryGraph
{
	struct QEdge { int v, nxt; };
	QEdge e[M << 1]; int h[N], tot = 1;
	inline void add(int u, int v)
	{ e[++tot] = { v, h[u] }; h[u] = tot; }
} Q;
bool vis[N]; int res[N << 1];
inline void tarjanLCA(int u)
{
	vis[u] = 1;
	for (int i = T.h[u]; i; i = T.e[i].nxt)
	{
		int v = T.e[i].v;
		if (vis[v]) continue;
		tarjanLCA(v); fa[v] = u;
	}
	for (int i = Q.h[u]; i; i = Q.e[i].nxt)
	{
		int v = Q.e[i].v;
		if (vis[v])
		{
			res[i] = find(v);
			if (i & 1) res[i + 1] = res[i];
			else       res[i - 1] = res[i];
		}
	}
}
inline int LCA(int i) { return res[i << 1]; }
} using namespace TarjanLCA;

inline void tarjan(int u, int ine)
{
	dfn[u] = low[u] = ++dfncnt;
	for (int i = G.h[u]; i; i = G.e[i].nxt)
	{
		int v = G.e[i].v;
		if (!dfn[v])
		{
			tarjan(v, i);
			low[u] = min(low[u], low[v]);
			if (dfn[u] < low[v]) b[i] = b[i ^ 1] = 1;
		}
		else if (i != (ine ^ 1))
			low[u] = min(low[u], dfn[v]);
	}
}
inline void dfs(int u)
{
	dcc[u] = dcccnt;
	for (int i = G.h[u]; i; i = G.e[i].nxt)
	{
		int v = G.e[i].v;
		if (dcc[v] == dcc[u]) siz[dcccnt] += G.e[i].w;
		if (!b[i] && !dcc[v])
			dfs(v), siz[dcccnt] += G.e[i].w;
	}
}

inline void rebuild()
{
	for (int u = 1; u <= n; ++u)
		for (int i = G.h[u]; i; i = G.e[i].nxt)
		{
			int v = G.e[i].v;
			if (dcc[u] != dcc[v])
				T.add(dcc[u], dcc[v], G.e[i].w);
		}
	rep (i, 1, dcccnt) sum[i] = siz[i];
}

inline void fix(int u, int fa)
{
	sum[u] += sum[fa];
	for (int i = T.h[u]; i; i = T.e[i].nxt)
	{
		int v = T.e[i].v;
		if (v == fa) continue;
		sum[v] += T.e[i].w; fix(v, u);
	}
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	cin >> n >> m;

	rep (i, 1, m)
	{
		int u, v, w; cin >> u >> v >> w;
		G.add(u, v, w); G.add(v, u, w);
	}

	rep (i, 1, n) if (!dfn[i]) tarjan(i, 0);
	rep (i, 1, n) if (!dcc[i]) ++dcccnt, dfs(i);

	rebuild(); fix(1, 0);

	cin >> q;

	rep (i, 1, q)
	{
		int u, v; cin >> u >> v;
		qry[i] = { dcc[u], dcc[v] };
		Q.add(dcc[u], dcc[v]);
		Q.add(dcc[v], dcc[u]);
	}

	init(dcccnt); tarjanLCA(1);

	rep (i, 1, q)
	{
		int f = LCA(i);
		int u = qry[i].first, v = qry[i].second;
		if (sum[u] + sum[v] - (sum[f] << 1) + siz[f] > 0)
			cout << "YES" << endl;
		else
			cout << "NO" << endl;
	}

	return 0;
}
2023/11/3 21:20
加载中...