佬大求调,玄关
查看原帖
佬大求调,玄关
1198462
dvsfanjo楼主2024/6/7 00:24
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e4 + 5, M = 5e4 + 5;
struct edge
{
	int x, y, k;
	void read()
	{
		cin >> x >> y >> k;
		return;
	}
};
bool cmp(edge x, edge y) {return x.k > y.k;}
int n, m, vis[N][N], tot, dis[N][N], v[N], ans, q, px, py, dep[N], f[N][N], ans1;
vector<int> T[N], G[N];
edge e[N], t[N];
struct ULS
{
	int p[N];
	void ini()
	{
		for (int i = 0; i < N; i++)
			p[i] = i;
		return;
	}
	int get(int x)//并查集
	{
		if (x == p[x])
			return x;
		return p[x] = get(p[x]);
	}
} s1, s2;
void xxx(int x, int y)
{
	G[x].push_back(y);
	G[y].push_back(x);
	return;
}
void read()//输入
{
	cin >> n >> m;
	for (int i = 1; i <= m; i++)
		e[i].read(), xxx(e[i].x, e[i].y);
	for (int i = 1; i <= m; i++)
		dis[e[i].x][e[i].y] = dis[e[i].y][e[i].x] = e[i].k;
	s1.ini();
	return;
}
void dfs(int u, int fa)//搜连通块
{
	int dx = s2.get(u), dy = s2.get(fa);
	if (dx != dy)
		s2.p[dx] = dy;
	if (vis[fa][u])
		return;
	vis[fa][u] = vis[u][fa] = true;
	v[u] = v[fa] = true;
	if (u != fa)
		t[++tot] = {u, fa, dis[u][fa]};
	for (int i = 0; i < (int)G[u].size(); i++)
		dfs(G[u][i], u);
	return;
}
void dfs2(int u, int fa)
{
	dep[u] = dep[fa] + 1;
	f[u][0] = fa;
	for (int i = 1; i < 20; i++)
		f[u][i] = f[f[u][i - 1]][i - 1];
	for (int i = 0; i < (int)T[u].size(); i++)
		if (T[u][i] != fa)
			dfs(T[u][i], u);
	return;
}
void Kruskal()//Kruskal
{
	sort(t + 1, t + tot + 1, cmp);
	for (int i = 1; i <= tot; i++)
	{
		int dx = s1.get(t[i].x);
		int dy = s1.get(t[i].y);
		if (dx == dy) continue;
		T[t[i].x].push_back(t[i].y);
		T[t[i].y].push_back(t[i].x);
		s1.p[dx] = dy;
		ans += dis[t[i].x][t[i].y];
	}
	dfs2(t[1].x, 0);
	return;
}
int lca(int u, int v)//acllcaacllcaacllcaacllcaacllca
{
	if (u == v)
		return u;
	if (dep[u] < dep[v])
		swap(u, v);
	for (int i = 19; i >= 0; i--)
		if (dep[f[u][i]] >= dep[v])
			u = f[u][i], ans = min(ans, f[u][i]);
	for (int i = 19; i >= 0; i--)
		if (f[u][i] != f[v][i])
			u = f[u][i], v = f[v][i], ans = min(ans, min(f[u][i], f[v][i]));
	return min(ans, f[u][0]);
}
int main()
{
	read();
	s2.ini();
	for (int i = 1; i <= n; i++)
		if (!v[i])
		{
			dfs(i, i);
			Kruskal();
			cout << ans << endl;
			tot = ans = 0;
		}
	//极其丑陋的代码构建最大生成森林
	cin >> q;
	while (q--)
	{
		cin >> px >> py;
		if (s2.get(px) != s2.get(py))
		{
			cout << -1 << '\n';
			continue;
		}
		ans1 = 2e9;
		cout << lca(px, py) << endl;
	}
	return 0;
}

极其丑陋,求调,ans2算不出来

2024/6/7 00:24
加载中...