UVALive - 3211 - Now or later(2-SAT)

Problem   UVALive - 3211 - Now or later

Time Limit: 9000 mSec

Problem Description

Input

 The input contains several blocks of test cases. Each case begins with a line containing two integers 1 ≤ n ≤ 100000 and 1 ≤ m ≤ 100000. The number n is the number of astronauts. The next n lines specify the age of the n astronauts; each line contains a single integer number between 0 and 200. The next m lines contains two integers each, separated by a space. A line containing i and j (1 ≤ i,j ≤ n) means that the i-th astronaut and the j-th astronaut hate each other. The input is terminated by a block with n = m = 0.

Output

 For each test case, you have to output n lines, each containing a single letter. This letter is either ‘A’, ‘B’, or ‘C’. The i-th line describes which mission the i-th astronaut is assigned to. Astronauts that hate each other should not be assigned to the same mission, only young astronauts should be assigned to Mission B and only senior astronauts should be assigned to Mission A. If there is no such assignment, then output the single line ‘No solution.’ (without quotes).

Sample Input

16 20 21 22 23 24 25 26 27 28 101 102 103 104 105 106 107 108 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 10 2 9 3 12 4 11 5 14 6 13 7 16 8 15 1 12 1 13 3 16 6 15 0 0

Sample Output

B C C B C B C B A C C A C A C A

题解:几乎是2-SAT板子题,节点之间的关系稍微复杂了一点,总体来说并不困难。两种人,老年人只能做A,C,年轻人只能做B,C,所以每种人分别对应两种人格(其实就是true和false)如果相互厌恶的两人同类,那么不能同为true,也不能同为false,如果不同类,就只需不同为false(对应C)即可,至于输出方案,mark数组就是答案。

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 #define REP(i, n) for (int i = 1; i <= (n); i++)
  6 #define sqr(x) ((x) * (x))
  7 
  8 const int maxn = 100000 + 100;
  9 const int maxm = 30 + 10;
 10 const int maxs = 10000 + 10;
 11 
 12 typedef long long LL;
 13 typedef pair<int, int> pii;
 14 typedef pair<double, double> pdd;
 15 
 16 const LL unit = 1LL;
 17 const int INF = 0x3f3f3f3f;
 18 const LL mod = 1000000007;
 19 const double eps = 1e-14;
 20 const double inf = 1e15;
 21 const double pi = acos(-1.0);
 22 
 23 struct TwoSAT
 24 {
 25     int n, mark[maxn * 2];
 26     vector<int> G[maxn * 2];
 27     int S[maxn * 2], c;
 28 
 29     void init(int n)
 30     {
 31         this->n = n;
 32         memset(mark, 0, sizeof(mark));
 33         for (int i = 0; i < 2 * n; i++)
 34         {
 35             G[i].clear();
 36         }
 37     }
 38 
 39     bool dfs(int x)
 40     {
 41         if (mark[x ^ 1])
 42             return false;
 43         if (mark[x])
 44             return true;
 45 
 46         mark[x] = true;
 47         S[c++] = x;
 48         for (auto v : G[x])
 49         {
 50             if (!dfs(v))
 51                 return false;
 52         }
 53         return true;
 54     }
 55 
 56     bool solve()
 57     {
 58         for (int i = 0; i < 2 * n; i += 2)
 59         {
 60             if (!mark[i] && !mark[i + 1])
 61             {
 62                 c = 0;
 63                 if (!dfs(i))
 64                 {
 65                     while (c > 0)
 66                     {
 67                         mark[S[--c]] = 0;
 68                     }
 69                     if (!dfs(i + 1))
 70                         return false;
 71                 }
 72             }
 73         }
 74         return true;
 75     }
 76 
 77     void add_clause(int x, int xval, int y, int yval)
 78     {
 79         x = x * 2 + xval;
 80         y = y * 2 + yval;
 81         G[x ^ 1].push_back(y);
 82         G[y ^ 1].push_back(x);
 83     }
 84 };
 85 
 86 int n, m, sum;
 87 int age[maxn];
 88 TwoSAT solver;
 89 
 90 bool is_young(int x)
 91 {
 92     return x * n < sum;
 93 }
 94 
 95 main()
 96 {
 97     ios::sync_with_stdio(false);
 98     cin.tie(0);
 99     //freopen("input.txt", "r", stdin);
100     //freopen("output.txt", "w", stdout);
101     while (cin >> n >> m && (n || m))
102     {
103         solver.init(n);
104         sum = 0;
105         for (int i = 0; i < n; i++)
106         {
107             cin >> age[i];
108             sum += age[i];
109         }
110         int u, v;
111         for (int i = 0; i < m; i++)
112         {
113             cin >> u >> v;
114             if (u == v)
115                 continue;
116             u--, v--;
117             if (is_young(age[u]) == is_young(age[v]))
118             {
119                 solver.add_clause(u, 0, v, 0);
120                 solver.add_clause(u, 1, v, 1);
121             }
122             else
123             {
124                 solver.add_clause(u, 1, v, 1);
125             }
126         }
127         if (solver.solve())
128         {
129             for (int i = 0; i < 2 * n; i += 2)
130             {
131                 int a = age[i / 2];
132                 if (a * n >= sum)
133                 {
134                     if (solver.mark[i])
135                     {
136                         cout << "C" << endl;
137                     }
138                     else
139                     {
140                         cout << "A" << endl;
141                     }
142                 }
143                 else
144                 {
145                     if (solver.mark[i])
146                     {
147                         cout << "C" << endl;
148                     }
149                     else
150                     {
151                         cout << "B" << endl;
152                     }
153                 }
154             }
155         }
156         else
157         {
158             cout << "No solution." << endl;
159         }
160     }
161     return 0;
162 }

猜你喜欢

转载自www.cnblogs.com/npugen/p/10753205.html
now