示例#1
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var(people, friends, blocks) = inputStream.ReadValue <int, int, int>();
            var uf = new UnionFindTree(people);

            var friendsCount = new int[people];

            for (int i = 0; i < friends; i++)
            {
                var(a, b) = inputStream.ReadValue <int, int>();
                a--;
                b--;
                uf.Unite(a, b);
                friendsCount[a]++;
                friendsCount[b]++;
            }

            var blockCounts = new int[people];

            for (int i = 0; i < blocks; i++)
            {
                var(c, d) = inputStream.ReadValue <int, int>();
                c--;
                d--;
                if (uf.IsInSameGroup(c, d))
                {
                    blockCounts[c]++;
                    blockCounts[d]++;
                }
            }

            yield return(Enumerable.Range(0, people).Select(i => uf.GetGroupSizeOf(i) - friendsCount[i] - blockCounts[i] - 1).Join(' '));
        }
示例#2
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var(citiesCount, roadsCount, k) = inputStream.ReadValue <int, int, long>();
            var roads = new PriorityQueue <Road>(false);

            for (int i = 0; i < roadsCount; i++)
            {
                var(a, b, c) = inputStream.ReadValue <int, int, int>();
                a--;
                b--;
                roads.Enqueue(new Road(a, b, c));
            }

            var cities    = new UnionFindTree(citiesCount);
            var totalCost = 0;

            while (roads.Count > 0 && cities.Groups > k)
            {
                var road = roads.Dequeue();
                if (!cities.IsInSameGroup(road.From, road.To))
                {
                    cities.Unite(road.From, road.To);
                    totalCost += road.Cost;
                }
            }

            yield return(totalCost);
        }
示例#3
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var(cityCount, roadCount, finalCount) = inputStream.ReadValue <int, int, int>();
            var edges = new Queue <Edge>(Enumerable.Repeat(0, roadCount).Select(_ =>
            {
                var(u, v, c) = inputStream.ReadValue <int, int, int>();
                u--;
                v--;
                return(new Edge(u, v, c));
            }).OrderBy(e => e));

            var unionFind = new UnionFindTree(cityCount);

            var totalCost = 0;

            while (unionFind.Groups > finalCount)
            {
                var edge = edges.Dequeue();
                if (!unionFind.IsInSameGroup(edge.From, edge.To))
                {
                    unionFind.Unite(edge.From, edge.To);
                    totalCost += edge.Cost;
                }
            }

            yield return(totalCost);
        }
示例#4
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var n      = inputStream.ReadInt();
            var robots = new Robot[n];

            for (int i = 0; i < n; i++)
            {
                var xd = inputStream.ReadIntArray();
                robots[i] = new Robot(xd[0], xd[1]);
            }

            Array.Sort(robots);
            Array.Reverse(robots);

            var unitedRobots = new UnionFindTree(robots.Select(r => r.Destination));
            var destinations = new SegmentTree <int>(robots.Select(r => r.Destination).ToArray(), (d1, d2) => Math.Max(d1, d2), int.MinValue);

            const int mod    = 998244353;
            var       counts = new Modular[robots.Length + 1];

            for (int i = 0; i < counts.Length; i++)
            {
                counts[i] = new Modular(0, mod);
            }
            counts[0] = new Modular(1, mod);

            for (int i = 0; i < robots.Length; i++)
            {
                var currentRobot      = robots[i];
                var inRangeRobotIndex = BoundaryBinarySearch(mid => robots[mid].Coordinate < currentRobot.Destination, -1, i);

                while (!unitedRobots.IsInSameGroup(inRangeRobotIndex, i))
                {
                    var hasntUnited = BoundaryBinarySearch(mid => !unitedRobots.IsInSameGroup(mid, i), i, inRangeRobotIndex);
                    unitedRobots.Unite(hasntUnited, i);
                }

                var outOfRangeRobotIndex = BoundaryBinarySearch(mid => !unitedRobots.IsInSameGroup(mid, i), i, -1);

                counts[i + 1] += counts[i] + counts[outOfRangeRobotIndex + 1];
            }

            yield return(counts[robots.Length].Value);
        }
示例#5
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var(n, pairCount) = inputStream.ReadValue <int, int>();
            var p     = inputStream.ReadIntArray().Select(i => i - 1).ToArray();
            var pairs = new UnionFindTree(n);

            for (int i = 0; i < pairCount; i++)
            {
                var(x, y) = inputStream.ReadValue <int, int>();
                x--;
                y--;
                pairs.Unite(x, y);
            }

            yield return(Enumerable.Range(0, n).Count(i => pairs.IsInSameGroup(p[i], i)));
        }
示例#6
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var cityCount    = inputStream.ReadInt();
            var xCoordinates = new IndexCoordinatePair[cityCount];
            var yCoordinates = new IndexCoordinatePair[cityCount];

            for (int i = 0; i < xCoordinates.Length; i++)
            {
                var xy = inputStream.ReadIntArray();
                var x  = xy[0];
                var y  = xy[1];
                xCoordinates[i] = new IndexCoordinatePair(i, x);
                yCoordinates[i] = new IndexCoordinatePair(i, y);
            }

            Array.Sort(xCoordinates);
            Array.Sort(yCoordinates);

            var cityPairs = new List <CityPair>();

            for (int i = 0; i + 1 < cityCount; i++)
            {
                var xDiff = xCoordinates[i + 1].Coordinate - xCoordinates[i].Coordinate;
                var yDiff = yCoordinates[i + 1].Coordinate - yCoordinates[i].Coordinate;
                cityPairs.Add(new CityPair(xCoordinates[i].Index, xCoordinates[i + 1].Index, xDiff));
                cityPairs.Add(new CityPair(yCoordinates[i].Index, yCoordinates[i + 1].Index, yDiff));
            }

            cityPairs.Sort();

            var  unionFind = new UnionFindTree(cityCount);
            long totalCost = 0;

            foreach (var cityPair in cityPairs)
            {
                if (!unionFind.IsInSameGroup(cityPair.CityA, cityPair.CityB))
                {
                    totalCost += cityPair.Distance;
                    unionFind.Unite(cityPair.CityA, cityPair.CityB);
                }
            }

            yield return(totalCost);
        }
示例#7
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var nm           = inputStream.ReadIntArray();
            var islandsCount = nm[0];
            var bridgesCount = nm[1];

            var bridges = new Bridge[bridgesCount];

            for (int i = 0; i < bridges.Length; i++)
            {
                var ab = inputStream.ReadIntArray();
                var a  = ab[0] - 1;
                var b  = ab[1] - 1;
                bridges[i] = new Bridge(a, b);
            }

            var inconvenienceDiff = new Stack <long>(bridgesCount);
            var islandGroups      = new UnionFindTree(islandsCount);

            foreach (var bridge in bridges.Reverse())
            {
                if (!islandGroups.IsInSameGroup(bridge.IslandA, bridge.IslandB))
                {
                    long groupA = islandGroups.GetGroupSizeOf(bridge.IslandA);
                    long groupB = islandGroups.GetGroupSizeOf(bridge.IslandB);
                    inconvenienceDiff.Push(groupA * groupB);
                    islandGroups.Unite(bridge.IslandA, bridge.IslandB);
                }
                else
                {
                    inconvenienceDiff.Push(0);
                }
            }

            long total = 0;

            foreach (var diff in inconvenienceDiff)
            {
                total += diff;
                yield return(total);
            }
        }
示例#8
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var townsCount = inputStream.ReadInt();
            var plan       = inputStream.ReadIntArray().Select(i => i - 1).ToArray();

            int baseRoads = 0;
            var unionFind = new UnionFindTree(townsCount);

            for (int town = 0; town < plan.Length; town++)
            {
                if (plan[town] >= 0 && !unionFind.IsInSameGroup(town, plan[town]))
                {
                    unionFind.Unite(town, plan[town]);
                    baseRoads++;
                }
            }

            var parents = new int[townsCount];

            for (int i = 0; i < parents.Length; i++)
            {
                parents[i] = unionFind.GetRootOf(i);
            }

            var roots      = parents.Distinct().ToArray();
            var dictionary = new Dictionary <int, int>();

            foreach (var group in parents.GroupBy(i => i))
            {
                dictionary[group.Key] = group.Count();
            }

            for (int i = 0; i < roots.Length; i++)
            {
                for (int j = i + 1; j < roots.Length; j++)
                {
                }
            }
        }
示例#9
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var nm           = inputStream.ReadIntArray();
            var islandsCount = nm[0];
            var bridgesCount = nm[1];

            var bridges = new Bridge[bridgesCount];

            for (int i = 0; i < bridgesCount; i++)
            {
                var ab = inputStream.ReadIntArray();
                bridges[i] = new Bridge(ab[0] - 1, ab[1] - 1);
            }

            var conveniences = new long[bridgesCount + 1];
            var islands      = new UnionFindTree(islandsCount);

            for (int i = bridges.Length - 1; i >= 0; i--)
            {
                var bridge = bridges[i];
                conveniences[i] = conveniences[i + 1];

                if (!islands.IsInSameGroup(bridge.Island1, bridge.Island2))
                {
                    conveniences[i] += (long)islands.GetGroupSizeOf(bridge.Island1) * islands.GetGroupSizeOf(bridge.Island2);
                    islands.Unite(bridge.Island1, bridge.Island2);
                }
            }

            long unconvenience = 0;

            for (int i = 0; i < bridges.Length; i++)
            {
                unconvenience += conveniences[i] - conveniences[i + 1];
                yield return(unconvenience);
            }
        }