結果

問題 No.274 The Wall
ユーザー 鳩でもわかるC#鳩でもわかるC#
提出日時 2024-07-05 16:45:38
言語 C#
(.NET 8.0.203)
結果
AC  
実行時間 100 ms / 2,000 ms
コード長 5,098 bytes
コンパイル時間 14,680 ms
コンパイル使用メモリ 169,028 KB
実行使用メモリ 191,900 KB
最終ジャッジ日時 2024-07-05 16:45:58
合計ジャッジ時間 16,764 ms
ジャッジサーバーID
(参考情報)
judge1 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 53 ms
30,080 KB
testcase_01 AC 54 ms
30,208 KB
testcase_02 AC 53 ms
30,080 KB
testcase_03 AC 55 ms
30,592 KB
testcase_04 AC 62 ms
30,720 KB
testcase_05 AC 61 ms
30,720 KB
testcase_06 AC 56 ms
30,720 KB
testcase_07 AC 56 ms
30,976 KB
testcase_08 AC 58 ms
30,720 KB
testcase_09 AC 54 ms
30,192 KB
testcase_10 AC 57 ms
30,720 KB
testcase_11 AC 56 ms
30,848 KB
testcase_12 AC 77 ms
33,024 KB
testcase_13 AC 71 ms
34,560 KB
testcase_14 AC 66 ms
32,256 KB
testcase_15 AC 69 ms
32,640 KB
testcase_16 AC 59 ms
30,960 KB
testcase_17 AC 55 ms
30,848 KB
testcase_18 AC 53 ms
30,848 KB
testcase_19 AC 77 ms
33,280 KB
testcase_20 AC 100 ms
33,152 KB
testcase_21 AC 80 ms
33,152 KB
testcase_22 AC 81 ms
33,152 KB
testcase_23 AC 89 ms
33,792 KB
testcase_24 AC 83 ms
33,280 KB
testcase_25 AC 82 ms
191,900 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
  復元対象のプロジェクトを決定しています...
  /home/judge/data/code/main.csproj を復元しました (118 ms)。
MSBuild のバージョン 17.9.6+a4ecab324 (.NET)
  main -> /home/judge/data/code/bin/Release/net8.0/main.dll
  main -> /home/judge/data/code/bin/Release/net8.0/publish/

ソースコード

diff #

using System;
using System.Collections.Generic;
using System.Linq;

class TwoSAT
{
    int N = 0;
    int nextId = 0;
    Vertex[] vertices = { };
    bool[] visits = { };

    // 連結リストと逆向きの連結リスト
    List<int>[] list = null;
    List<int>[] rlist = null;

    class Vertex
    {
        public Vertex(int num, int id)
        {
            Number = num;
            ID = id;
        }
        public int Number = 0;
        public int ID = 0;
    }

    public TwoSAT(int n)
    {
        N = n;

        // 連結リストを生成する
        list = new List<int>[n * 2];
        rlist = new List<int>[n * 2];

        for (int i = 0; i < n * 2; i++)
        {
            list[i] = new List<int>();
            rlist[i] = new List<int>();
        }
    }

    public void AddConstraint(bool xTrue, int x, bool yTrue, int y)
    {
        if (!xTrue)
            x = TakeNot(x);
        if (!yTrue)
            y = TakeNot(y);

        list[TakeNot(x)].Add(y);
        list[TakeNot(y)].Add(x);

        rlist[y].Add(TakeNot(x));
        rlist[x].Add(TakeNot(y));
    }

    int TakeNot(int x)
    {
        if (x < N)
            return x + N;
        else
            return x - N;
    }

    public List<bool> Solve()
    {
        visits = new bool[N * 2];
        vertices = new Vertex[N * 2];

        for (int i = 0; i < N * 2; i++)
            Dfs1(i, list);

        vertices = vertices.OrderByDescending(_ => _.ID).ToArray();

        int groupNumber = 0;
        Dictionary<int, int> dic = new Dictionary<int, int>();

        visits = new bool[N * 2];
        foreach (Vertex vertex in vertices)
        {
            List<int> ret = Dfs2(vertex.Number, rlist);
            foreach (int i in ret)
                dic.Add(i, groupNumber);

            groupNumber++;
        }

        List<bool> values = new List<bool>();
        for (int i = 0; i < N; i++)
        {
            if (dic[i] == dic[TakeNot(i)])
                return new List<bool>();

            if (dic[i] > dic[TakeNot(i)])
                values.Add(true);
            else
                values.Add(false);
        }
        return values;
    }

    void Dfs1(int vNum, List<int>[] list)
    {
        if (!visits[vNum])
        {
            visits[vNum] = true;
            dfs(vNum);
        }

        void dfs(int num)
        {
            foreach (int i in list[num])
            {
                if (visits[i])
                    continue;
                visits[i] = true;
                dfs(i);
            }
            vertices[num] = new Vertex(num, nextId++);
        }
    }

    List<int> Dfs2(int vNum, List<int>[] list)
    {
        List<int> rets = new List<int>(); // たどり着ける頂点をリストにして返す
        if (!visits[vNum]) // 一度訪問した頂点は対象外
        {
            rets.Add(vNum);
            visits[vNum] = true;
            dfs(vNum);
        }
        return rets;

        void dfs(int num)
        {
            foreach (int i in list[num])
            {
                if (visits[i])
                    continue;
                visits[i] = true;
                dfs(i);
                rets.Add(i);
            }
        }
    }
}

public class Program
{
    static void Main()
    {
        int N, M;
        {
            int[] vs = Console.ReadLine().Split().Select(_ => int.Parse(_)).ToArray();
            N = vs[0];
            M = vs[1];
        }

        int[] L = new int[N];
        int[] R = new int[N];
        for (int i = 0; i < N; i++)
        {
            int[] vs = Console.ReadLine().Split().Select(_ => int.Parse(_)).ToArray();
            L[i] = vs[0];
            R[i] = vs[1];
        }

        TwoSAT twoSAT = new TwoSAT(N);

        for (int a = 0; a < N; a++)
        {
            for (int b = a + 1; b < N; b++)
            {
                //L[a] R[a] L[b] R[b]
                bool b1 = (R[b] < L[a] || R[a] < L[b]);
                bool b2 = (M - L[b]- 1 < L[a] || R[a] < M - R[b]-1);
                if (b1 && !b2)
                {
                    twoSAT.AddConstraint(true, a, false, b);
                    twoSAT.AddConstraint(false, a, true, b);
                    //bad = false;
                }
                if (!b1 && b2)
                {
                    twoSAT.AddConstraint(true, a, true, b);
                    twoSAT.AddConstraint(false, a, false, b);
                    //Console.WriteLine("AA");

                    //bad = false;
                }
                if (!b1 && !b2)
                {
                    Console.WriteLine("NO");
                    return;
                }
            }
        }

        List<bool> rets = twoSAT.Solve();

        if (rets.Count == 0)
            Console.WriteLine("NO");
        else
        {
            Console.WriteLine("YES");
            //for (int i = 0; i < rets.Count; i++)
            //{
            //    if (rets[i])
            //        Console.WriteLine(X[i]);
            //    else
            //        Console.WriteLine(Y[i]);
            //}
        }
    }
}
0