Submission #52114743


Source Code Expand

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;

namespace Tasks;

public class E
{
    public static void Main()
    {
        using var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
        Console.SetOut(sw);
        Solve();
        Console.Out.Flush();
    }

    public static void Solve()
    {
        var N = Scanner.Scan<int>();
        var E = new (int A, int B)[N - 1];
        for (var i = 0; i < N - 1; i++)
        {
            var (a, b) = Scanner.Scan<int, int>();
            a--; b--;
            E[i] = (a, b);
        }

        var C = Scanner.ScanEnumerable<long>().ToArray();
        var dp = new ReRooting<Data>(N, new Operation(C));
        foreach (var (a, b) in E)
        {
            dp.AddEdge(a, b);
        }

        var result = dp.Calculate();
        var answer = result.Select(x => x.S).Min();
        Console.WriteLine(answer);
    }

    public class Operation : ReRooting<Data>.IOperation
    {
        public Data Identity => new Data(0, 0);

        private readonly long[] C;
        public Operation(long[] c) => C = c;

        public Data AddRoot(int i, Data value)
        {
            return new Data(value.S + value.C, value.C + C[i]);
        }

        public Data Merge(Data left, Data right)
        {
            return new Data(left.S + right.S, left.C + right.C);
        }
    }

    public readonly record struct Data(long S, long C);

    public class ReRooting<T>
    {
        public int Size { get; init; }
        private readonly List<int>[] _edges;
        private readonly IOperation _operation;
        public ReRooting(int size, IOperation operation)
        {
            Size = size;
            _operation = operation;
            _edges = new List<int>[Size];
            for (var i = 0; i < Size; i++) _edges[i] = new List<int>();
        }
        public void AddEdge(int u, int v)
        {
            _edges[u].Add(v);
            _edges[v].Add(u);
        }
        public T[] Calculate()
        {
            var result = new T[Size];
            Array.Fill(result, _operation.Identity);
            var dp = new T[Size][];
            Dfs(0);
            Bfs(0, _operation.Identity);
            return result;
            T Dfs(int u, int p = -1)
            {
                dp[u] = new T[_edges[u].Count];
                var cum = _operation.Identity;
                for (var i = 0; i < _edges[u].Count; i++)
                {
                    var v = _edges[u][i];
                    if (v == p) continue;
                    dp[u][i] = Dfs(v, u);
                    cum = _operation.Merge(cum, dp[u][i]);
                }
                return _operation.AddRoot(u, cum);
            }
            void Bfs(int u, T value, int p = -1)
            {
                var n = _edges[u].Count;
                for (var i = 0; i < n; i++)
                {
                    if (_edges[u][i] == p) dp[u][i] = value;
                }
                var cumL = new T[n + 1];
                var cumR = new T[n + 1];
                Array.Fill(cumL, _operation.Identity);
                Array.Fill(cumR, _operation.Identity);
                for (var i = 0; i < n; i++)
                {
                    var j = n - 1 - i;
                    cumL[i + 1] = _operation.Merge(cumL[i], dp[u][i]);
                    cumR[j] = _operation.Merge(cumR[j + 1], dp[u][j]);
                }
                result[u] = _operation.AddRoot(u, cumL[n]);
                for (var i = 0; i < n; i++)
                {
                    var v = _edges[u][i];
                    if (v != p) Bfs(v, _operation.AddRoot(u, _operation.Merge(cumL[i], cumR[i + 1])), u);
                }
            }
        }
        public interface IOperation
        {
            public T Identity { get; }
            public T Merge(T left, T right);
            public T AddRoot(int i, T value);
        }
    }

    public static class Scanner
    {
        public static T Scan<T>() where T : IConvertible => Convert<T>(ScanStringArray()[0]);
        public static (T1, T2) Scan<T1, T2>() where T1 : IConvertible where T2 : IConvertible
        {
            var input = ScanStringArray();
            return (Convert<T1>(input[0]), Convert<T2>(input[1]));
        }
        public static (T1, T2, T3) Scan<T1, T2, T3>() where T1 : IConvertible where T2 : IConvertible where T3 : IConvertible
        {
            var input = ScanStringArray();
            return (Convert<T1>(input[0]), Convert<T2>(input[1]), Convert<T3>(input[2]));
        }
        public static (T1, T2, T3, T4) Scan<T1, T2, T3, T4>() where T1 : IConvertible where T2 : IConvertible where T3 : IConvertible where T4 : IConvertible
        {
            var input = ScanStringArray();
            return (Convert<T1>(input[0]), Convert<T2>(input[1]), Convert<T3>(input[2]), Convert<T4>(input[3]));
        }
        public static (T1, T2, T3, T4, T5) Scan<T1, T2, T3, T4, T5>() where T1 : IConvertible where T2 : IConvertible where T3 : IConvertible where T4 : IConvertible where T5 : IConvertible
        {
            var input = ScanStringArray();
            return (Convert<T1>(input[0]), Convert<T2>(input[1]), Convert<T3>(input[2]), Convert<T4>(input[3]), Convert<T5>(input[4]));
        }
        public static (T1, T2, T3, T4, T5, T6) Scan<T1, T2, T3, T4, T5, T6>() where T1 : IConvertible where T2 : IConvertible where T3 : IConvertible where T4 : IConvertible where T5 : IConvertible where T6 : IConvertible
        {
            var input = ScanStringArray();
            return (Convert<T1>(input[0]), Convert<T2>(input[1]), Convert<T3>(input[2]), Convert<T4>(input[3]), Convert<T5>(input[4]), Convert<T6>(input[5]));
        }
        public static IEnumerable<T> ScanEnumerable<T>() where T : IConvertible => ScanStringArray().Select(Convert<T>);
        private static string[] ScanStringArray()
        {
            var line = Console.ReadLine()?.Trim() ?? string.Empty;
            return string.IsNullOrEmpty(line) ? Array.Empty<string>() : line.Split(' ');
        }
        private static T Convert<T>(string value) where T : IConvertible => (T)System.Convert.ChangeType(value, typeof(T));
    }
}

Submission Info

Submission Time
Task E - Minimize Sum of Distances
User AconCavy
Language C# 11.0 (.NET 7.0.7)
Score 475
Code Size 6454 Byte
Status AC
Exec Time 226 ms
Memory 95508 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 475 / 475
Status
AC × 3
AC × 31
Set Name Test Cases
Sample example0.txt, example1.txt, example2.txt
All example0.txt, example1.txt, example2.txt, test_00.txt, test_01.txt, test_02.txt, test_03.txt, test_04.txt, test_05.txt, test_06.txt, test_07.txt, test_08.txt, test_09.txt, test_10.txt, test_11.txt, test_12.txt, test_13.txt, test_14.txt, test_15.txt, test_16.txt, test_17.txt, test_18.txt, test_19.txt, test_20.txt, test_21.txt, test_22.txt, test_23.txt, test_24.txt, test_25.txt, test_26.txt, test_27.txt
Case Name Status Exec Time Memory
example0.txt AC 62 ms 26556 KiB
example1.txt AC 54 ms 27036 KiB
example2.txt AC 54 ms 26488 KiB
test_00.txt AC 129 ms 52280 KiB
test_01.txt AC 109 ms 48748 KiB
test_02.txt AC 139 ms 61232 KiB
test_03.txt AC 79 ms 39916 KiB
test_04.txt AC 134 ms 55796 KiB
test_05.txt AC 106 ms 51404 KiB
test_06.txt AC 123 ms 57508 KiB
test_07.txt AC 112 ms 58532 KiB
test_08.txt AC 93 ms 53612 KiB
test_09.txt AC 194 ms 71724 KiB
test_10.txt AC 170 ms 64888 KiB
test_11.txt AC 203 ms 71912 KiB
test_12.txt AC 159 ms 64544 KiB
test_13.txt AC 195 ms 71936 KiB
test_14.txt AC 174 ms 64692 KiB
test_15.txt AC 183 ms 77232 KiB
test_16.txt AC 163 ms 63940 KiB
test_17.txt AC 180 ms 77428 KiB
test_18.txt AC 157 ms 63480 KiB
test_19.txt AC 180 ms 77444 KiB
test_20.txt AC 157 ms 63872 KiB
test_21.txt AC 226 ms 95508 KiB
test_22.txt AC 190 ms 87388 KiB
test_23.txt AC 221 ms 90164 KiB
test_24.txt AC 188 ms 78988 KiB
test_25.txt AC 225 ms 91680 KiB
test_26.txt AC 186 ms 83968 KiB
test_27.txt AC 58 ms 26512 KiB