56分(4WA,1TLE)求条
查看原帖
56分(4WA,1TLE)求条
1217860
yexuanqi楼主2025/7/22 15:58
using namespace std;

#define int long long
const int M = 3e5 + 10, N = 2e5 + 10, K = 30,  INF = 0x3f3f3f3f3f3f3f3f;

int p[N];
int h[N], e[2 * M], w[2 * M], ne[2 * M], idx;
int n, m, kruskal_ans, cnt;
int fa[N][K], se[N][K], th[N][K];
int depth[N];
bool st[N];

inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return x*f;
}
struct Edge
{
	int u, v, w;
	bool operator < (const Edge &s) { return w < s.w; }
}edge[M];
int find(int x)
{
	if(x != p[x]) x = find(p[x]);
	return p[x];
}
void add(int a, int b, int c)
{
	e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}
void dfs(int u, int father, int ww)
{
	depth[u] = depth[father] + 1;
	fa[u][0] = father;
	se[u][0] = ww;
	th[u][0] = -INF;
	for(int k = 1; k < K; k ++)
	{
		fa[u][k] = fa[fa[u][k - 1]][k - 1];
		se[u][k] = max(se[u][k - 1], se[fa[u][k - 1]][k - 1]);
		th[u][k] = max(th[u][k - 1], th[fa[u][k - 1]][k - 1]);
		if(se[u][k - 1] > se[fa[u][k - 1]][k - 1])
			th[u][k] = max(th[u][k], se[fa[u][k - 1]][k - 1]);
		else if(se[u][k - 1] < se[fa[u][k - 1]][k - 1])
			th[u][k] = max(th[u][k], se[u][k - 1]);
	}
	for(int i = h[u]; ~i; i = ne[i])
	{
		int j = e[i];
		if(j == father) continue;
		dfs(j, u, w[i]);
	}
}
void kruskal()
{
	sort(edge, edge + m);
	for(int i = 0; i < m; i ++)
	{
		int u = find(edge[i].u), v = find(edge[i].v);
		if(u == v) continue;
		st[i] = true;
		kruskal_ans += edge[i].w;
		p[u] = v;
		add(edge[i].u, edge[i].v, edge[i].w);
		add(edge[i].v, edge[i].u, edge[i].w);
		if(++ cnt == n - 1) break;
	}
}
int lca(int u, int v)
{
	if(depth[u] < depth[v]) swap(u, v);
	for(int k = K - 1; k > 0; k --)
		if(depth[fa[u][k]] > depth[v]) u = fa[u][k];
	if(u == v) return u;
	for(int k = K - 1; k > 0; k --)
		if(fa[u][k] > fa[v][k])
			u = fa[u][k], v = fa[v][k];
	return fa[u][0];
}
int maxw(int u, int v, int maxx)
{
	int res = -INF;
	for(int k = K - 1; k >= 0; k --)
		if(depth[fa[u][k]] >= depth[v])
		{
			if(maxx != se[u][k]) res = max(res, se[u][k]);
			else res = max(res, th[u][k]);
			u = fa[u][k];
		}
	return res;
}
void calc()
{
	int res = INF;
	for(int i = 0; i < m; i ++)
	{
		if(st[i]) continue;
		int p = lca(edge[i].u, edge[i].v);
		int maxu = maxw(edge[i].u, p, edge[i].w);
		int maxv = maxw(edge[i].v, p, edge[i].w);
		res = min(res, kruskal_ans - max(maxu, maxv) + edge[i].w);
	}
	printf("%lld\n", res);
}
signed main()
{
	memset(h, -1, sizeof h);
	n = read(), m = read();
	for(int i = 1; i <= n; i ++) p[i] = i;
	for(int i = 0; i < m; i ++)
		edge[i].u = read(), edge[i].v = read(), edge[i].w = read();
	kruskal();
	dfs(1, 0, 0);
	calc();
	
	return 0;
}

提交记录

2025/7/22 15:58
加载中...