예제 #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(cityCount, roadCount) = inputStream.ReadValue <int, int>();
            var roads   = GetRoads(inputStream, roadCount);
            var queries = inputStream.ReadInt();
            var people  = new Person[queries];

            for (int i = 0; i < people.Length; i++)
            {
                var(v, w) = inputStream.ReadValue <int, int>();
                v--;
                people[i] = new Person(v, w, i);
            }
            Array.Sort(people);
            var results   = new int[queries];
            var unionFind = new UnionFindTree(cityCount);

            for (int i = 0; i < people.Length; i++)
            {
                while (roads.Count > 0 && roads.Peek().Year > people[i].Year)
                {
                    var road = roads.Dequeue();
                    unionFind.Unite(road.From, road.To);
                }

                results[people[i].Index] = unionFind.GetGroupSizeOf(people[i].From);
            }

            foreach (var result in results)
            {
                yield return(result);
            }
        }
예제 #3
0
        static void Main(string[] args)
        {
            var           inputs = Console.ReadLine().Split(' ').Select(x => int.Parse(x)).ToArray();
            var           N      = inputs[0];
            var           Q      = inputs[1];
            UnionFindTree uf     = new UnionFindTree(N);

            for (int i = 0; i < Q; ++i)
            {
                inputs       = Console.ReadLine().Split(' ').Select(x => int.Parse(x)).ToArray();
                var(p, a, b) = (inputs[0], inputs[1], inputs[2]);

                if (p == 0)
                {
                    //連結
                    uf.Unite(a, b);
                }
                else
                {
                    //判定
                    if (uf.Same(a, b))
                    {
                        Console.WriteLine("Yes");
                    }
                    else
                    {
                        Console.WriteLine("No");
                    }
                }
            }
        }
예제 #4
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);
        }
예제 #5
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);
        }
예제 #6
0
    public int maxProfit(int N, int M, int K, int[] a, int[] b, int[] v)
    {
        var railways = new Railway[M];

        for (int i = 0; i < railways.Length; i++)
        {
            railways[i] = new Railway(a[i], b[i], v[i]);
        }
        Array.Sort(railways);
        var queue  = new Queue <Railway>(railways);
        var needed = new Queue <Railway>();

        var count  = 0;
        var result = 0;

        while (queue.Count > 1 && count < K)
        {
            var unionFind = new UnionFindTree(N);

            var trying = queue.Dequeue();

            foreach (var railway in needed)
            {
                unionFind.Unite(railway.CityA, railway.CityB);
            }

            foreach (var railway in queue)
            {
                unionFind.Unite(railway.CityA, railway.CityB);
            }

            if (unionFind.Groups == 1)
            {
                result += trying.Cost;
                count++;
            }
            else
            {
                needed.Enqueue(trying);
            }
        }

        return(result);
    }
예제 #7
0
        bool IsConnected(int nodeCount, Edge[] edges, int removed)
        {
            var uf = new UnionFindTree(nodeCount);

            for (int i = 0; i < edges.Length; i++)
            {
                if (i != removed)
                {
                    uf.Unite(edges[i].From, edges[i].To);
                }
            }

            return(uf.Groups == 1);
        }
예제 #8
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var(n, m) = inputStream.ReadValue <int, int>();
            var unionFind = new UnionFindTree(n);

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

            yield return(unionFind.Groups);
        }
예제 #9
0
        public override void Solve(IOManager io)
        {
            var cities = io.ReadInt();
            var roads  = io.ReadInt();
            var uf     = new UnionFindTree(cities);

            for (int i = 0; i < roads; i++)
            {
                var a = io.ReadInt() - 1;
                var b = io.ReadInt() - 1;
                uf.Unite(a, b);
            }

            io.WriteLine(uf.Groups - 1);
        }
예제 #10
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var n = inputStream.ReadInt();
            var a = inputStream.ReadIntArray().Select((v, i) => new ValueAndIndex(v, i)).ToArray();
            var b = inputStream.ReadIntArray().Select((v, i) => new ValueAndIndex(v, i)).ToArray();

            Array.Sort(a);
            Array.Sort(b);

            if (!InitialCheck(a, b))
            {
                yield return("No");
            }
            else
            {
                var swapLoops = new UnionFindTree(n);
                for (int i = 0; i < a.Length; i++)
                {
                    swapLoops.Unite(a[i].Index, b[i].Index);
                }

                if (swapLoops.Groups > 1)
                {
                    yield return("Yes");
                }
                else
                {
                    var ok = false;
                    for (int i = 0; i + 1 < b.Length; i++)
                    {
                        if (a[i + 1].Value <= b[i].Value)
                        {
                            ok = true;
                            break;
                        }
                    }

                    if (ok)
                    {
                        yield return("Yes");
                    }
                    else
                    {
                        yield return("No");
                    }
                }
            }
        }
예제 #11
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)));
        }
예제 #12
0
        public override void Solve(IOManager io)
        {
            var n  = io.ReadInt();
            var uf = new UnionFindTree(n);

            var towns = new Town[n];

            for (int i = 0; i < towns.Length; i++)
            {
                var x = io.ReadInt();
                var y = io.ReadInt();
                towns[i] = new Town(x, y, i);
            }

            Array.Sort(towns, (a, b) => a.X - b.X);

            var rbTree = new RedBlackTree <Town>();

            for (int i = 0; i < towns.Length; i++)
            {
                var toRemove = new Queue <Town>();

                foreach (var town in rbTree.EnumerateRange(new Town(0, 0, 0), towns[i]))
                {
                    uf.Unite(town.ID, towns[i].ID);
                    toRemove.Enqueue(town);
                }

                if (toRemove.Count > 0)
                {
                    toRemove.Dequeue();
                    while (toRemove.Count > 0)
                    {
                        rbTree.Remove(toRemove.Dequeue());
                    }
                }
                else
                {
                    rbTree.Add(towns[i]);
                }
            }

            for (int i = 0; i < uf.Count; i++)
            {
                io.WriteLine(uf.GetGroupSizeOf(i));
            }
        }
예제 #13
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var nm         = inputStream.ReadIntArray();
            var cards      = nm[0];
            var hints      = nm[1];
            var cardGroups = new UnionFindTree(cards);

            for (int i = 0; i < hints; i++)
            {
                var xyz = inputStream.ReadIntArray();
                var x   = xyz[0] - 1;
                var y   = xyz[1] - 1;
                cardGroups.Unite(x, y);
            }

            yield return(cardGroups.Groups);
        }
예제 #14
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);
        }
예제 #15
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);
        }
예제 #16
0
    static void Main()
    {
        SetOut(new StreamWriter(OpenStandardOutput())
        {
            AutoFlush = false
        });
        var I = G;
        int N = I[0], M = I[1];
        var uf = new UnionFindTree(N);

        for (var i = 0; i < M; i++)
        {
            I = G;
            int a = I[0] - 1, b = I[1] - 1;
            uf.Unite(a, b);
        }
        var Q  = int.Parse(ReadLine());
        var sb = new StringBuilder();

        while (Q-- > 0)
        {
            I = G;
            int x = I[0] - 1, y = I[1] - 1, z = I[2], l = 0, r = M + 1;
            while (l < r)
            {
                var t = (l + r) / 2;
                int p = uf.Find(t, x), q = uf.Find(t, y), s = p == q?uf.GetSize(t, p) : uf.GetSize(t, p) + uf.GetSize(t, q);

                if (s >= z)
                {
                    r = t;
                }
                else
                {
                    l = t + 1;
                }
            }
            sb.AppendLine(l.ToString());
        }
        Write(sb);
        Out.Flush();
    }
예제 #17
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);
            }
        }
예제 #18
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var(n, k, l) = inputStream.ReadValue <int, int, int>();
            var roads    = new UnionFindTree(n);
            var railways = new UnionFindTree(n);

            for (int i = 0; i < k; i++)
            {
                var(p, q) = inputStream.ReadValue <int, int>();
                p--;
                q--;
                roads.Unite(p, q);
            }

            for (int i = 0; i < l; i++)
            {
                var(r, s) = inputStream.ReadValue <int, int>();
                r--;
                s--;
                railways.Unite(r, s);
            }

            var counter = new Counter <RootPair>();
            var pairs   = new RootPair[n];

            for (int i = 0; i < n; i++)
            {
                var pair = new RootPair(roads._nodes[i].FindRoot().ID, railways._nodes[i].FindRoot().ID);
                pairs[i] = pair;
                counter[pair]++;
            }

            var results = new Queue <long>();

            foreach (var pair in pairs)
            {
                results.Enqueue(counter[pair]);
            }

            yield return(results.Join(' '));
        }
예제 #19
0
        public override IEnumerable <object> Solve(TextReader inputStream)
        {
            var(people, relations) = inputStream.ReadValue <int, int>();
            var unionFind = new UnionFindTree(people);

            for (int i = 0; i < relations; i++)
            {
                var(a, b) = inputStream.ReadValue <int, int>();
                a--;
                b--;
                unionFind.Unite(a, b);
            }

            var max = 0;

            for (int i = 0; i < unionFind.Count; i++)
            {
                max = Math.Max(max, unionFind.GetGroupSizeOf(i));
            }

            yield return(max);
        }
예제 #20
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++)
                {
                }
            }
        }
예제 #21
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);
            }
        }