I have been doing this question a few days ago, but I never did it. I will do it again today.
The Code provided by Liu rujia is wrong, but the error cannot be found. I hope someone will remind me of the error!
Each astronaut only corresponds to A, C, B, and C. Therefore, we only remember two vertices: C and non-C.
For every conflicting person, if one chooses C and the other selects non-C, that is, C1-> non-C2 and C2-> non-C1;
If they are of the same age, if one person chooses not C, the other person can only select C, that is, non-C1-> C2 and non-C2-> C1; (these two sides may not exist)
In this way, each pair of contradictions can form two or four sides.
After the figure is created, it is a typical 2-SAT problem. It is implemented using DFS!
# Include <stdio. h> # include <string. h ># include <vector> using namespace STD; const int maxn = 100000 + 10; vector <int> adj [maxn * 2]; bool flag [maxn * 2]; bool eld [maxn]; // true indicates that the age is sufficient for int n, m, age [maxn]; int mystack [maxn * 2], top; // I represents 2 * I and 2 * I + 1, 2 * I represents a and B, 2 * I + 1 represents cvoid Init () {for (INT I = 1; I <= N; I ++) {adj [2 * I]. clear (), adj [2 * I + 1]. clear (); flag [2 * I] = false, flag [2 * I + 1] = false;} int sum = 0; For (INT I = 1; I <= N; I ++) {scanf ("% d", & age [I]); sum + = age [I] ;}for (INT I = 1; I <= N; I ++) if (age [I] * n <sum) // young eld [I] = false; else eld [I] = true; int A, B; For (INT I = 1; I <= m; I ++) {scanf ("% d", & A, & B ); // A and B brothers, A and B adj [2 * A + 1]. push_back (2 * B); adj [2 * B + 1]. push_back (2 * A); // If C is selected for either of the two, only if (ELD [a] = eld [B]) can be selected. // if the age group is the same {adj [2 * A]. push_back (2 * B + 1); adj [2 * B]. push_back (2 * A + 1) ;}} bool DFS (INT cur ){ Int sibling = cur ^ 1; if (flag [sibling]) return false; If (flag [cur]) return true; flag [cur] = true; mystack [top ++] = cur; For (vector <int>: iterator it = adj [cur]. begin (); it! = Adj [cur]. End (); It ++) if (! DFS (* It) return false; return true;} void resolve () {While (top! = 0) {int ans = mystack [-- top]; flag [ANS] = false ;}} bool solve () {for (INT I = 1; I <= N; I ++) {If (flag [2 * I] | flag [2 * I + 1]) continue; Top = 0; If (! DFS (2 * I) {resolve (); // restore the selected if (! DFS (2 * I + 1) return false;} return true;} int main () {While (scanf ("% d", & N, & M )! = EOF & N + M) {Init (); If (! Solve () printf ("no solution. \ n "); else {for (INT I = 1; I <= N; I ++) {If (flag [2 * I + 1]) printf ("C \ n"); else if (! Eld [I]) // young printf ("B \ n"); else printf ("A \ n") ;}} return 0 ;}