1 import java
.io
.FileReader
;
2 import java
.io
.IOException
;
3 import java
.io
.PrintWriter
;
4 import java
.util
.ArrayList
;
5 import java
.util
.Scanner
;
6 import java
.util
.StringTokenizer
;
8 public class exclusive_mb
implements Runnable
{
10 private PrintWriter out
;
12 private static final int NUM_NODES
= 15;
19 private final Node
[] nodes
= new Node
[NUM_NODES
];
25 private final ArrayList
<Edge
> edges
= new ArrayList
<Edge
>();
27 public static void main(String
[] args
) {
28 new Thread(new exclusive_mb()).start();
33 in
= new Scanner(new FileReader("exclusive.in"));
34 out
= new PrintWriter("exclusive.out");
40 } catch (IOException e
) {
45 private int nameToIndex(char ch
) {
49 private char indexToName(int index
) {
50 return (char) ('L' + index
);
53 private void solve() {
54 for (int i
= 0; i
< NUM_NODES
; i
++) {
55 nodes
[i
] = new Node();
58 final int numEdges
= in
.nextInt();
60 for (int i
= 0; i
< numEdges
; i
++) {
61 StringTokenizer stringTokenizer
= new StringTokenizer(in
.nextLine());
62 Edge edge
= new Edge();
63 edge
.a
= nameToIndex(stringTokenizer
.nextToken().charAt(0));
64 edge
.b
= nameToIndex(stringTokenizer
.nextToken().charAt(0));
66 if ((nodes
[edge
.a
].edgesMask
& (1 << edge
.b
)) == 0) {
67 nodes
[edge
.a
].edgesMask
|= (1 << edge
.b
);
68 nodes
[edge
.b
].edgesMask
|= (1 << edge
.a
);
72 for (int i
= 0; i
< 1 << NUM_NODES
; i
++) {
73 coloringSize
[i
] = Integer
.MAX_VALUE
;
76 final int allMask
= (1 << NUM_NODES
) - 1;
77 final int waitChainLength
= computeMinColoring(allMask
) - 2;
78 out
.println(waitChainLength
);
83 final int newMask
= coloringBacktrack
[mask
];
84 final int stableMask
= mask
& ~newMask
;
85 for (int i
: unpackMask(stableMask
)) {
86 nodes
[i
].color
= color
;
92 for (Edge edge
: edges
) {
93 if (nodes
[edge
.a
].color
< nodes
[edge
.b
].color
) {
94 out
.printf("%c %c\n", indexToName(edge
.a
), indexToName(edge
.b
));
96 out
.printf("%c %c\n", indexToName(edge
.b
), indexToName(edge
.a
));
101 private final int[] coloringSize
= new int[1 << NUM_NODES
];
102 private final int[] coloringBacktrack
= new int[1 << NUM_NODES
];
104 private int[] unpackMask(int mask
) {
106 for (int i
= 0; i
< NUM_NODES
; i
++) {
107 if ((mask
& (1 << i
)) != 0) {
111 int[] result
= new int[numNodes
];
113 for (int i
= 0; i
< NUM_NODES
; i
++) {
114 if ((mask
& (1 << i
)) != 0) {
121 private int computeMinColoring(int mask
) {
122 if (coloringSize
[mask
] != Integer
.MAX_VALUE
) {
123 return coloringSize
[mask
];
130 final int[] list
= unpackMask(mask
);
131 tryStableSet(list
, 0, mask
, 0, 0);
133 return coloringSize
[mask
];
136 private void tryStableSet(int[] list
, int listIndex
, int totalMask
, int stableMask
, int neighborMask
) {
137 if (listIndex
== list
.length
) {
138 if (stableMask
!= 0) {
139 final int newMask
= totalMask
& ~stableMask
;
140 final int size
= computeMinColoring(newMask
) + 1;
141 if (coloringSize
[totalMask
] > size
) {
142 coloringSize
[totalMask
] = size
;
143 coloringBacktrack
[totalMask
] = newMask
;
147 tryStableSet(list
, listIndex
+ 1, totalMask
, stableMask
, neighborMask
);
149 final int j
= list
[listIndex
];
150 final int thisMask
= 1 << j
;
151 if ((neighborMask
& thisMask
) == 0) {
152 tryStableSet(list
, listIndex
+ 1, totalMask
, stableMask
| thisMask
, neighborMask
| nodes
[j
].edgesMask
);