using System;
using System.Collections.Generic;
using System.Linq;
public class Edge : IComparable<Edge>
{
public int weight, id, u, v;
public Edge(int weight, int id, int u, int v)
{
this.weight = weight;
this.id = id;
this.u = u;
this.v = v;
}
// Compare edges based on weights
public int CompareTo(Edge other)
{
return this.weight.CompareTo(other.weight);
}
}
public class MainClass
{
static int[,] ancestor = new int[200005, 50];
static int[] depth = new int[200005];
static int[,] maxWeight = new int[200005, 50];
static int[] parent = new int[200005];
static int[] subtreeSize = new int[200005];
static bool[] included = new bool[200005];
static List<int[]>[] adjacencyList = new List<int[]>[200005];
static List<Edge> edges = new List<Edge>();
static List<Edge> queries = new List<Edge>();
static MainClass()
{
for (int i = 0; i < 200005; i++)
{
adjacencyList[i] = new List<int[]>();
}
}
// Function to find the Lowest Common Ancestor (LCA) and maximum weight on the path
static int FindLCA(int u, int v)
{
int ans = -1;
if (depth[u] != depth[v])
{
if (depth[u] < depth[v])
{
int temp = u;
u = v;
v = temp;
}
int k = depth[u] - depth[v];
for (int i = 0; (1 << i) <= k; i++)
{
if ((k >> i & 1) == 1)
{
ans = Math.Max(ans, maxWeight[u, i]);
u = ancestor[u, i];
}
}
}
if (u == v)
return ans;
int k2 = (int)(Math.Log(depth[u]) / Math.Log(2));
for (int i = k2; i >= 0; i--)
{
if (ancestor[u, i] != ancestor[v, i])
{
ans = Math.Max(Math.Max(maxWeight[u, i], maxWeight[v, i]), ans);
u = ancestor[u, i];
v = ancestor[v, i];
}
}
return Math.Max(Math.Max(ans, maxWeight[u, 0]), maxWeight[v, 0]);
}
// Depth-first search to construct ancestor and maxWeight arrays
static void Dfs(int u)
{
foreach (var x in adjacencyList[u])
{
int v = x[0];
int weight = x[1];
if (v == ancestor[u, 0])
continue;
ancestor[v, 0] = u;
maxWeight[v, 0] = weight;
depth[v] = depth[u] + 1;
for (int j = 1; j <= 20; j++)
{
ancestor[v, j] = ancestor[ancestor[v, j - 1], j - 1];
maxWeight[v, j] = Math.Max(maxWeight[ancestor[v, j - 1], j - 1],
maxWeight[v, j - 1]);
}
Dfs(v);
}
}
// Function to find the parent of a node using path compression
static int FindParent(int u)
{
if (u == parent[u])
return u;
return parent[u] = FindParent(parent[u]);
}
// Function to join two sets using union by size
static void UnionSets(int u, int v)
{
u = FindParent(u);
v = FindParent(v);
if (subtreeSize[u] < subtreeSize[v])
{
int temp = u;
u = v;
v = temp;
}
subtreeSize[u] += subtreeSize[v];
parent[v] = u;
}
public static void Main()
{
int n = 5, m = 7;
int[] weightList = { 3, 1, 5, 2, 3, 2, 4 };
int[] uList = { 1, 1, 1, 2, 2, 3, 4 };
int[] vList = { 2, 3, 4, 3, 5, 4, 5 };
for (int i = 1; i <= m; i++)
{
int u = uList[i - 1], v = vList[i - 1], weight = weightList[i - 1];
queries.Add(new Edge(weight, i, u, v));
edges.Add(new Edge(weight, i, u, v));
}
edges.Sort();
int totalWeight = 0;
for (int i = 1; i <= n; i++)
{
parent[i] = i;
subtreeSize[i] = 1;
}
foreach (var x in edges)
{
int weight = x.weight, u = x.u, v = x.v;
int parentU = FindParent(u);
int parentV = FindParent(v);
if (parentU == parentV)
continue;
totalWeight += weight;
included[x.id] = true;
UnionSets(u, v);
adjacencyList[u].Add(new int[] { v, weight });
adjacencyList[v].Add(new int[] { u, weight });
}
Dfs(1);
foreach (var x in queries)
{
int weight = x.weight, u = x.u, v = x.v;
if (included[x.id])
{
Console.Write(totalWeight + " ");
continue;
}
int lcaWeight = FindLCA(u, v);
Console.Write(totalWeight - lcaWeight + weight + " ");
}
}
}
// This code is contributed by shivamgupta310570