求HACK数据,90pts,第一个点WA(各位佬看看呗)
查看原帖
求HACK数据,90pts,第一个点WA(各位佬看看呗)
183881
_shy楼主2022/12/24 23:15
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 100, maxm = 3e5 + 100;
const int maxlg = 20;
int n, m, mx;
long long ans;
// 最小生成树,链式前向行
int head[maxn], cnt; 
struct edge 
{
	int v, w, next;
} e[maxn << 1];
// 题给的图 
int cnti;
struct edgei
{
	int u, v, w;
} ei[maxm];
bool cmp (edgei a, edgei b) {return a.w < b.w;}
void add (int u, int v, int w, int tp) 
{
	if (tp == 0) 
		ei[++ cnti] = (edgei) {u, v, w};
	else if (tp == 1) 
		e[++ cnt] = (edge) {v, w, head[u]},
		head[u] = cnt; 
} 
int fa[maxn], vis[maxm], tot;
int find (int x) 
{
	while (x != fa[x]) x = fa[x] = fa[fa[x]];
	return x;
}
void Init () 
{
	for (int i = 1; i <= n; i++)
		fa[i] = i;
	sort (ei + 1, ei + cnti + 1, cmp);
}
void Kruskal () 
{
	Init ();
	for (int i = 1; i <= cnti; i++) 
	{
		int u = ei[i].u, v = ei[i].v, 
			w = ei[i].w;
		int x = find (u), y = find (v);
		if (x == y) continue;
		fa[x] = y;
		add (u, v, w, 1), add (v, u, w, 1);
		vis[i] = 1, ans += w;
		if ((++ tot) == n - 1) break;
	}
}
int val[maxn][maxlg + 5], anc[maxn][maxlg + 5], depth[maxn];
void dfs (int u, int fa, int d) 
{
	anc[u][0] = fa, depth[u] = d;
	for (int i = head[u]; i; i = e[i].next) 
	{
		int v = e[i].v, w = e[i].w;
		if (v == fa) continue;
		val[v][0] = w;
		dfs (v, u, d + 1);
	}
}
void Initi () 
{
	for (int j = 1; j <= maxlg; j++)
		for (int i = 1; i <= n; i++) 
			anc[i][j] = anc[anc[i][j - 1]][j - 1],
			val[i][j] = max (val[i][j - 1], val[anc[i][j - 1]][j - 1]);
}
void swim (int &x, int h, int w) 
{
	for (int i = 0; h; i++) 
	{
		if (h & 1) 
			mx = (val[x][i] < w ? max (mx, val[x][i]) : mx), 
			x = anc[x][i];
		h >>= 1;
	}
}
void lca (int x, int y, int w) 
{
	if (depth[x] < depth[y]) swap (x, y);
	swim (x, depth[x] - depth[y], w);
	if (x == y) return;
	for (int i = maxlg; i >= 0 && anc[x][0] != anc[y][0]; i--) 
	{
		if (anc[x][i] != anc[y][i])
			mx = (val[x][i] < w ? max (mx, val[x][i]) : mx),
			mx = (val[y][i] < w ? max (mx, val[y][i]) : mx),
			x = anc[x][i], y = anc[y][i];
	}
	mx = (val[x][0] < w ? max (mx, val[x][0]) : mx),
	mx = (val[y][0] < w ? max (mx, val[y][0]) : mx);
	return;
}
int main ()
{
	scanf ("%d %d", &n, &m);
	for (int i = 1; i <= m; i++) 
	{
		int u, v, w;
		scanf ("%d %d %d", &u, &v, &w);
		if (u == v) continue;
		add (u, v, w, 0);
	}
	Kruskal ();
	dfs (1, 0, 1), Initi ();
	int ansi = 2147483647;
	for (int i = 1; i <= cnti; i++) 
	{
		if (vis[i]) continue;
		int u = ei[i].u, v = ei[i].v, w = ei[i].w;
		mx = -1;
		lca (u, v, w);
		if (mx == -1) continue;
		ansi = min (ansi, w - mx);
	}
	printf ("%lld", ans + 1ll * ansi);
	return 0;
}


2022/12/24 23:15
加载中...