Пример #1
0
    bool IsOK(double pay)
    {
        var es = new Edge[E];

        for (var i = 0; i < E; i++)
        {
            es[i] = new Edge(a[i], b[i], c[i] - t[i] * pay);
        }
        Array.Sort(es);
        var uf    = new UnionFindTree(V);
        var total = 0.0;

        foreach (var e in es)
        {
            if (e.c <= 0 || !uf.IsSameCategory(e.a, e.b))
            {
                uf.UniteCategory(e.a, e.b);
                total += e.c;
                if (total > 0)
                {
                    break;
                }
            }
        }
        return(total <= 0);
    }
Пример #2
0
        /// <summary>
        /// メイン処理をここに書く
        /// </summary>
        void SolveOne()
        {
            int n = sc.nextInt();
            int m = sc.nextInt();

            int[][]       ls = new int[n][];
            UnionFindTree u  = new UnionFindTree(m + 1);

            for (int i = 0; i < n; i++)
            {
                int ki = sc.nextInt();
                ls[i] = sc.nextInt(ki);
                if (ki > 1)
                {
                    for (int lang = 1; lang < ki; lang++)
                    {
                        u.UniteCategory(ls[i][0], ls[i][lang]);
                    }
                }
            }
            bool ok = true;

            for (int man = 1; man < n; man++)
            {
                if (u.IsSameCategory(ls[0][0], ls[man][0]) == false)
                {
                    ok = false;
                }
            }
            pr.WriteLine(ok);
        }
Пример #3
0
    void Solve()
    {
        var I = G;
        int V = I[0], E = I[1];
        var es = new int[E][];

        for (var i = 0; i < E; i++)
        {
            es[i] = G;
        }
        var uf  = new UnionFindTree(V);
        var ans = new long[E];
        var sum = V * (V - 1L) / 2;

        for (var i = E - 1; i >= 0; i--)
        {
            ans[i] = sum;
            int u = es[i][0] - 1, v = es[i][1] - 1;
            if (!uf.IsSameCategory(u, v))
            {
                sum -= uf.GetSize(u) * (long)uf.GetSize(v);
                uf.UniteCategory(u, v);
            }
        }
        for (var i = 0; i < E; i++)
        {
            WriteLine(ans[i]);
        }
    }
Пример #4
0
        /// <summary>
        /// メイン処理をここに書く
        /// </summary>
        void SolveOne()
        {
            int n = sc.nextInt();
            int m = sc.nextInt();

            int[] p = sc.nextInt(n);
            for (int i = 0; i < n; i++)
            {
                p[i]--;
            }
            int[]         x  = new int[m];
            int[]         y  = new int[m];
            UnionFindTree uf = new UnionFindTree(n);

            for (int i = 0; i < m; i++)
            {
                x[i] = sc.nextInt() - 1;
                y[i] = sc.nextInt() - 1;
                uf.UniteCategory(x[i], y[i]);
            }
            int ans = 0;

            for (int i = 0; i < n; i++)
            {
                if (uf.IsSameCategory(p[i], i))
                {
                    ans++;
                }
            }
            Console.WriteLine(ans);
        }
Пример #5
0
    void Solve()
    {
        var I = G();
        int N = I[0], M = I[1];
        var es = new Edge[M + N];

        for (var i = 0; i < N; i++)
        {
            es[i] = new Edge(i, N, F());
        }
        for (var i = 0; i < M; i++)
        {
            I         = G();
            es[N + i] = new Edge(I[0] - 1, I[1] - 1, I[2]);
        }
        Array.Sort(es);
        var uf  = new UnionFindTree(N + 1);
        var sum = 0L;
        var c   = 0;

        foreach (var e in es)
        {
            if (!uf.IsSameCategory(e.From, e.To))
            {
                uf.UniteCategory(e.From, e.To);
                sum += e.Cost;
                if (++c == N)
                {
                    break;
                }
            }
        }
        WriteLine(sum);
    }
Пример #6
0
    void Solve()
    {
        //var start = DateTime.Now;
        ps   = new double[N, D];
        hash = new Bits[N];
        Generate((uint)F());
        var es = new List <Edge>();

        for (var i = 0; i < N; i++)
        {
            for (var j = i + 1; j < N; j++)
            {
                if (hash[i].Distance(hash[j]) < 92)
                {
                    es.Add(new Edge(i, j, Cost(i, j)));
                }
            }
        }
        es.Sort();
        var uf   = new UnionFindTree(5000);
        var cost = 0.0;
        var k    = 0;

        foreach (var e in es)
        {
            if (!uf.IsSameCategory(e.From, e.To))
            {
                cost += e.Cost;
                uf.UniteCategory(e.From, e.To);
                Console.WriteLine("{0} {1}", e.From + 1, e.To + 1);
                if (++k == N - 1)
                {
                    break;
                }
            }
        }
        for (var i = 1; i < N; i++)
        {
            if (!uf.IsSameCategory(0, i))
            {
                throw new Exception();
            }
        }
        //Console.WriteLine(cost);
        //var end = DateTime.Now;
        //Console.WriteLine("{0}", (end - start).TotalSeconds);
    }
Пример #7
0
    void Solve()
    {
        var I = G();
        int N = I[0], Q = I[1];
        var uf = new UnionFindTree(2 * N);

        for (var i = 0; i < Q; i++)
        {
            I = G();
            int x = I[1] - 1, y = I[2] - 1, z = I[3] % 2;
            if (I[0] == 1)
            {
                uf.UniteCategory(2 * x, 2 * y + z);
                uf.UniteCategory(2 * x + 1, 2 * y + (1 - z));
            }
            else
            {
                WriteLine(uf.IsSameCategory(2 * x, 2 * y) ? "YES" : "NO");
            }
        }
    }
Пример #8
0
    bool IsOK(double pay)
    {
        var es = new Tuple <int, int, double> [E];

        for (var i = 0; i < E; i++)
        {
            es[i] = new Tuple <int, int, double>(a[i], b[i], c[i] - t[i] * pay);
        }
        Array.Sort(es, (x, y) => x.Item3.CompareTo(y.Item3));
        var uf    = new UnionFindTree(V);
        var total = 0.0;

        foreach (var e in es)
        {
            if (e.Item3 <= 0 || !uf.IsSameCategory(e.Item1, e.Item2))
            {
                uf.UniteCategory(e.Item1, e.Item2);
                total += e.Item3;
            }
        }
        return(total <= 0);
    }
Пример #9
0
        /// <summary>
        /// メイン処理をここに書く
        /// </summary>
        void SolveOne()
        {
            n = sc.nextInt();
            a = sc.nextInt() - 1;
            b = sc.nextInt() - 1;
            x = new int[n];
            y = new int[n];
            u = new UnionFindTree(n);
            for (int i = 0; i < n; i++)
            {
                x[i] = sc.nextInt();
                y[i] = sc.nextInt();
            }
            int d = Dist(a, b);

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    if (Dist(i, j) == d)
                    {
                        u.UniteCategory(i, j);
                    }
                }
            }
            long reach = 0;

            for (int i = 0; i < n; i++)
            {
                if (u.IsSameCategory(a, i))
                {
                    reach++;
                }
            }
            long ans = reach * (reach - 1) / 2;

            Console.WriteLine(ans);
        }
Пример #10
0
    void Solve()
    {
        var I = G;

        N  = I[0];
        M  = I[1];
        es = new Tuple <int, int> [M];
        for (var i = 0; i < M; i++)
        {
            I     = G;
            es[i] = new Tuple <int, int>(I[0], I[1]);
        }
        Q  = F;
        qs = new Tuple <int, int, int> [Q];
        for (var i = 0; i < Q; i++)
        {
            I     = G;
            qs[i] = new Tuple <int, int, int>(I[0], I[1], I[2]);
        }
        {
            var i = 1;
            while (i < M)
            {
                i <<= 1;
            }
            var tmp = new Tuple <int, int> [i];
            for (var j = 0; j < M; j++)
            {
                tmp[j] = new Tuple <int, int>(es[j].Item1 - 1, es[j].Item2 - 1);
            }
            for (var j = M; j < i; j++)
            {
                tmp[j] = new Tuple <int, int>(0, 0);
            }
            es = tmp; M = i;
            for (var j = 0; j < Q; j++)
            {
                qs[j] = new Tuple <int, int, int>(qs[j].Item1 - 1, qs[j].Item2 - 1, qs[j].Item3);
            }
        }
        var log = MSB((uint)M);
        var seg = new List <int> [2 * M - 1];

        for (var i = 0; i < 2 * M - 1; i++)
        {
            seg[i] = new List <int>();
        }
        var node = 0;

        for (var i = 0; i < Q; i++)
        {
            seg[node].Add(i);
        }
        for (var i = 0; i < log; i++)
        {
            var uf  = new UnionFindTree(N);
            var mod = 1 << (log - i);
            var e   = 0;
            for (var j = mod >> 1; j < M; j += mod)
            {
                for (; e < j; e++)
                {
                    uf.UniteCategory(es[e].Item1, es[e].Item2);
                }
                foreach (var q in seg[node])
                {
                    int x = qs[q].Item1, y = qs[q].Item2, z = qs[q].Item3, w = 0;
                    if (uf.IsSameCategory(x, y))
                    {
                        w = uf.GetSize(x);
                    }
                    else
                    {
                        w = uf.GetSize(x) + uf.GetSize(y);
                    }
                    if (w >= z)
                    {
                        seg[2 * node + 1].Add(q);
                    }
                    else
                    {
                        seg[2 * node + 2].Add(q);
                    }
                }
                seg[node].Clear();
                node++;
            }
        }
        var ans = new int[Q];

        for (var i = M - 1; i < 2 * M - 1; i++)
        {
            foreach (var x in seg[i])
            {
                ans[x] = i - M + 1;
            }
        }
        for (var i = 0; i < Q; i++)
        {
            WriteLine(ans[i] + 1);
        }
    }