Problem:


Score : 100 points

Problem Statement

Consider placing N flags on a line. Flags are numbered through 1 to N.

Flag i can be placed on the coordinate X_i or Y_i.
For any two different flags, the distance between them should be at least D.

Decide whether it is possible to place all N flags. If it is possible, print such a configulation.

Constraints

1 \leq N \leq 1000

0 \leq D \leq 10^9

0 \leq X_i < Y_i \leq 10^9

All values in Input are integer.

Input

Input is given from Standard Input in the following format:

N D
X_1 Y_1
X_2 Y_2
\vdots
X_N Y_N

Output

Print No if it is impossible to place N flags.

If it is possible, print Yes first.
After that, print N lines. i-th line of them should contain the coodinate of flag i.

Sample Input 1

3 2
1 4
2 5
0 6

Sample Output 1

Yes
4
2
0

Sample Input 2

3 3
1 4
2 5
0 6

Sample Output 2

No



Sample input:
3 2
1 4
2 5
0 6


Sample output:
Yes
4
2
0

Submission status: Accepted

Solution code:
import sys

input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")


n,d = list(map(int, input().split()))
xy = [tuple(map(int, input().split())) for _ in range(n)]
class SAT2:
    def __init__(self, n):
        self.n = n
        self.ns = [[] for _ in range(2*n)]
    def add_clause(self, i, f, j, g):
        """(xi==f) and (xj==g)
        """
        n = self.n
        u0,u1 = (i,i+n) if f else (i+n,i)
        v0,v1 = (j,j+n) if g else (j+n,j)
        self.ns[u1].append(v0)
        self.ns[v1].append(u0)
    def solve(self):
        """強連結成分分解
        トポロジカルソート順の逆順に返す
        """
        preorder = {}
        lowlink = {}
        seen = [False]*(2*self.n)
        scc_queue = []
        i = 0  # Preorder counter
        # ans = [None]*(2*self.n)
        count = 1
        for source in range(2*self.n):
            if seen[source]:
                continue
            queue = [source]
            while queue:
                v = queue[-1]
                if v not in preorder:
                    i = i + 1
                    preorder[v] = i
                done = True
                for w in self.ns[v]:
                    if w not in preorder:
                        queue.append(w)
                        done = False
                        break
                if done:
                    lowlink[v] = preorder[v]
                    for w in self.ns[v]:
                        if seen[w]:
                            continue
                        if preorder[w] > preorder[v]:
                            lowlink[v] = min([lowlink[v], lowlink[w]])
                        else:
                            lowlink[v] = min([lowlink[v], preorder[w]])
                    queue.pop()
                    if lowlink[v] == preorder[v]:
                        scc = {v}
                        while scc_queue and preorder[scc_queue[-1]] > preorder[v]:
                            k = scc_queue.pop()
                            scc.add(k)
                        for v in scc:
                            seen[v] = count
                        count += 1
                    else:
                        scc_queue.append(v)
        ans = [None]*self.n
        for i in range(self.n):
            if seen[i]==seen[i+self.n]:
                return None
            elif seen[i]>seen[i+self.n]:
                # 上流にxがある: x-> not x : x==False
                ans[i] = False
            else:
                ans[i] = True
        return ans

solver = SAT2(n)
for i in range(n):
    for j in range(i+1,n):
        if abs(xy[i][0]-xy[j][0])<d:
            solver.add_clause(i,False,j,False)
        if abs(xy[i][0]-xy[j][1])<d:
            solver.add_clause(i,False,j,True)
        if abs(xy[i][1]-xy[j][0])<d:
            solver.add_clause(i,True,j,False)
        if abs(xy[i][1]-xy[j][1])<d:
            solver.add_clause(i,True,j,True)
ans = solver.solve()
if ans is not None:
    print("Yes")
    write("\n".join(map(str, [xy[i][0 if ans[i] else 1] for i in range(n)])))
else:
    print("No")

Submission status: Accepted

Solution code:
import sys

input = sys.stdin.buffer.readline


class StronglyConnectedComponets:
    def __init__(self, n: int) -> None:
        self.n = n
        self.edges = [[] for _ in range(n)]
        self.rev_edeges = [[] for _ in range(n)]
        self.vs = []
        self.order = [0] * n
        self.used = [False] * n

    def add_edge(self, from_v: int, to_v: int) -> None:
        self.edges[from_v].append(to_v)
        self.rev_edeges[to_v].append(from_v)

    def dfs(self, v: int) -> None:
        self.used[v] = True
        for child in self.edges[v]:
            if not self.used[child]:
                self.dfs(child)
        self.vs.append(v)

    def rdfs(self, v: int, k: int) -> None:
        self.used[v] = True
        self.order[v] = k
        for child in self.rev_edeges[v]:
            if not self.used[child]:
                self.rdfs(child, k)

    def run(self) -> int:
        self.used = [False] * self.n
        self.vs.clear()
        for v in range(self.n):
            if not self.used[v]:
                self.dfs(v)
        self.used = [False] * self.n
        k = 0
        for v in reversed(self.vs):
            if not self.used[v]:
                self.rdfs(v, k)
                k += 1
        return k


class TwoSat(StronglyConnectedComponets):
    def __init__(self, num_var: int) -> None:
        super().__init__(2 * num_var + 1)
        self.num_var = num_var
        self.ans = []

    def add_constraint(self, a: int, b: int) -> None:
        super().add_edge(self._neg(a), self._pos(b))
        super().add_edge(self._neg(b), self._pos(a))

    def _pos(self, v: int) -> int:
        return v if v > 0 else self.num_var - v

    def _neg(self, v: int) -> int:
        return self.num_var + v if v > 0 else -v

    def run(self) -> bool:
        super().run()
        self.ans.clear()
        for i in range(self.num_var):
            if self.order[i + 1] == self.order[i + self.num_var + 1]:
                return False
            self.ans.append(self.order[i + 1] > self.order[i + self.num_var + 1])
        return True


def main() -> None:
    N, D = map(int, input().split())

    flags = [tuple(int(x) for x in input().split()) for _ in range(N)]

    # (X_i, Y_i) -> (i, -i) (i=1, ..., N) と考える
    sat = TwoSat(N)

    # 節 a, b の距離が D 以下の場合，
    # a -> -b つまり -a or -b が成立しなければならない
    for i, (x_i, y_i) in enumerate(flags, 1):
        for j, (x_j, y_j) in enumerate(flags[i:], i+1):
            if abs(x_i - x_j) < D:
                sat.add_constraint(-i, -j)
            if abs(y_i - x_j) < D:
                sat.add_constraint(i, -j)
            if abs(x_i - y_j) < D:
                sat.add_constraint(-i, j)
            if abs(y_i - y_j) < D:
                sat.add_constraint(i, j)
    if sat.run():
        print("Yes")
        print(*[x_i if sat.ans[i] else y_i for i, (x_i, y_i) in enumerate(flags)], sep="\n")
    else:
        print("No")


if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
from itertools import product
import sys

input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 6 + 100)


class StronglyConnectedComponets:
    def __init__(self, n: int) -> None:
        self.n = n
        self.edges = [[] for _ in range(n)]
        self.rev_edeges = [[] for _ in range(n)]
        self.vs = []
        self.order = [0] * n
        self.used = [False] * n

    def add_edge(self, from_v: int, to_v: int) -> None:
        self.edges[from_v].append(to_v)
        self.rev_edeges[to_v].append(from_v)

    def dfs(self, v: int) -> None:
        self.used[v] = True
        for child in self.edges[v]:
            if not self.used[child]:
                self.dfs(child)
        self.vs.append(v)

    def rdfs(self, v: int, k: int) -> None:
        self.used[v] = True
        self.order[v] = k
        for child in self.rev_edeges[v]:
            if not self.used[child]:
                self.rdfs(child, k)

    def run(self) -> int:
        self.used = [False] * self.n
        self.vs.clear()
        for v in range(self.n):
            if not self.used[v]:
                self.dfs(v)
        self.used = [False] * self.n
        k = 0
        for v in reversed(self.vs):
            if not self.used[v]:
                self.rdfs(v, k)
                k += 1
        return k


class TwoSat(StronglyConnectedComponets):
    def __init__(self, num_var: int) -> None:
        super().__init__(2 * num_var + 1)
        self.num_var = num_var
        self.ans = []

    def add_constraint(self, a: int, b: int) -> None:
        super().add_edge(self._neg(a), self._pos(b))
        super().add_edge(self._neg(b), self._pos(a))

    def _pos(self, v: int) -> int:
        return v if v > 0 else self.num_var - v

    def _neg(self, v: int) -> int:
        return self.num_var + v if v > 0 else -v

    def run(self) -> bool:
        super().run()
        self.ans.clear()
        for i in range(self.num_var):
            if self.order[i + 1] == self.order[i + self.num_var + 1]:
                return False
            self.ans.append(self.order[i + 1] > self.order[i + self.num_var + 1])
        return True


def main() -> None:
    N, D = map(int, input().split())

    flags = [tuple(int(x) for x in input().split()) for _ in range(N)]

    # (X_i, Y_i) -> (i, -i) (i=1, ..., N) と考える
    sat = TwoSat(N)

    # 節 a, b の距離が D 以下の場合，
    # a -> -b つまり -a or -b が成立しなければならない
    for i, (x_i, y_i) in enumerate(flags, 1):
        for j, (x_j, y_j) in enumerate(flags[i:], i+1):
            if abs(x_i - x_j) < D:
                sat.add_constraint(-i, -j)
            if abs(y_i - x_j) < D:
                sat.add_constraint(i, -j)
            if abs(x_i - y_j) < D:
                sat.add_constraint(-i, j)
            if abs(y_i - y_j) < D:
                sat.add_constraint(i, j)
    if sat.run():
        print("Yes")
        print(*[x_i if sat.ans[i] else y_i for i, (x_i, y_i) in enumerate(flags)], sep="\n")
    else:
        print("No")


if __name__ == "__main__":
    main()

Submission status: Runtime Error

Solution code:
n,d = (int(x) for x in input().split())
lists = [[] for i in range(n)]
for j in range(n):
  lists[j] = list(map(int,input().split()))
  
c = 1
for i in range(n):
  c *= i+1

dists = []
for i in range(n-1):
  for j in range(i+1,n):
    dist = ( (lists[i][0] -lists[j][0]) + (lists[i][1]-lists[j][1]) )**2
    dists.append(dist)
    
for i in range(c):
  if d > dists[i]:
    print('No')
  else:
    print('Yes')

Submission status: Runtime Error

Solution code:
from scipy.sparse.csgraph import connected_components
from scipy.sparse import csr_matrix

N, D, *XY = map(int, open(0).read().split())
XY = list(zip(*[iter(XY)] * 2))

R, C = [], []
for i, (x1, y1) in enumerate(XY):
    for j, (x2, y2) in enumerate(XY):
        if i == j:
            continue

        if abs(x1 - x2) < D:
            R.append(i)
            C.append(j + N)
        if abs(x1 - y2) < D:
            R.append(i)
            C.append(j)
        if abs(y1 - x2) < D:
            R.append(i + N)
            C.append(j + N)
        if abs(y1 - y2) < D:
            R.append(i + N)
            C.append(j)

G = csr_matrix(([1] * len(R), (R, C)))
M, label = connected_components(G, connection='strong')

C = [[] for _ in range(M)]
for i, l in enumerate(label):
    C[l].append(i)

memo = {}
for c in C:
    for x in c:
        if (x < N and x + N in c) or (N <= x and x - N in c):
            print("No")
            quit()

        if x not in memo:
            memo[x] = True
            memo[(x + N) % (2 * N)] = False

print("Yes")
for i, (x, y) in enumerate(XY):
    print(x if memo[i] else y)

Submission status: Runtime Error

Solution code:

import networkx as nx

import io
import os


input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
N, D = [int(x) for x in input().split()]
XY = [[int(x) for x in input().split()] for i in range(N)]


graph = nx.DiGraph()


# a_i = 0 means choose x, a_i = 1 means choose y
# Store i for a_i==0 and i+N for a_i==1
for i, (x1, y1) in enumerate(XY):
    for j in range(N):
        if i != j:
            x2, y2 = XY[j]
            if abs(x1 - x2) < D:
                # a_i==0 => a_j==1
                graph.add_edge(i, j + N)
            if abs(x1 - y2) < D:
                # a_i==0 => a_j==0
                graph.add_edge(i, j)
            if abs(y1 - x2) < D:
                # a_i==1 => a_j==1
                graph.add_edge(i + N, j + N)
            if abs(y1 - y2) < D:
                # a_i==1 => a_j==0
                graph.add_edge(i + N, j)


SCC = nx.algorithms.components.strongly_connected_components(graph)
assignment = {}
for comp in SCC:
    for x in comp:
        if (x < N and x + N in comp) or (x >= N and x - N in comp):
            print("No")
            exit()
        if x not in assignment:
            assignment[x] = True
            assignment[(x + N) % (2 * N)] = False
print("Yes")
for i in range(N):
    print(XY[i][0] if assignment[i] else XY[i][1])

Submission status: Runtime Error

Solution code:
import sys

input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")


n,d = list(map(int, input().split()))
xy = [tuple(map(int, input().split())) for _ in range(n)]
class SAT2:
    def __init__(self, n):
        self.n = n
        self.ns = [[] for _ in range(2*n)]
    def add_clause(self, i, f, j, g):
        """(xi==f) and (xj==g)
        """
        u0,u1 = (i,i+n) if f else (i+n,i)
        v0,v1 = (j,j+n) if g else (j+n,j)
        self.ns[u1].append(v0)
        self.ns[v1].append(u0)
    def solve(self):
        """強連結成分分解
        トポロジカルソート順の逆順に返す
        """
        preorder = {}
        lowlink = {}
        seen = [False]*(2*self.n)
        scc_queue = []
        i = 0  # Preorder counter
        # ans = [None]*(2*self.n)
        count = 1
        for source in range(n):
            if seen[source]:
                continue
            queue = [source]
            while queue:
                v = queue[-1]
                if v not in preorder:
                    i = i + 1
                    preorder[v] = i
                done = True
                for w in self.ns[v]:
                    if w not in preorder:
                        queue.append(w)
                        done = False
                        break
                if done:
                    lowlink[v] = preorder[v]
                    for w in self.ns[v]:
                        if seen[w]:
                            continue
                        if preorder[w] > preorder[v]:
                            lowlink[v] = min([lowlink[v], lowlink[w]])
                        else:
                            lowlink[v] = min([lowlink[v], preorder[w]])
                    queue.pop()
                    if lowlink[v] == preorder[v]:
                        scc = {v}
                        while scc_queue and preorder[scc_queue[-1]] > preorder[v]:
                            k = scc_queue.pop()
                            scc.add(k)
                        # ans.append(scc)
#                         for v in scc:
#                             if v<self.n:
#                                 vv = v + self.n
#                             else:
#                                 vv = v - self.n
#                             if vv in scc:
#                                 return None
#                             if seen[vv]:
#                                 ans[vv] = True
#                                 ans[v] = False
                        for v in scc:
                            seen[v] = count
                        count += 1
                    else:
                        scc_queue.append(v)
        ans = [None]*self.n
        for i in range(self.n):
            if seen[i]==seen[i+self.n]:
                return None
            elif seen[i]>seen[i+self.n]:
                ans[i] = False
            else:
                ans[i] = True
        return ans

solver = SAT2(n)
for i in range(n):
    for j in range(n):
        if i==j:
            continue
        if abs(xy[i][0]-xy[j][0])<d:
            solver.add_clause(i,True,j,True)
        if abs(xy[i][0]-xy[j][1])<d:
            solver.add_clause(i,True,j,False)
        if abs(xy[i][1]-xy[j][0])<d:
            solver.add_clause(i,False,j,True)
        if abs(xy[i][1]-xy[j][1])<d:
            solver.add_clause(i,False,j,False)
ans = solver.solve()
if ans is not None:
    assert False
    print("Yes")
    write("\n".join(map(str, [xy[i][1 if ans[i] else 0] for i in range(n)])))
else:
    print("No")