Advertisement
trungore10

lamps.cpp

Sep 3rd, 2018
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.60 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef pair<int, int> ii;
  5.  
  6. const int N = 34, oo = 1e9+7;
  7. int n, T, col[N], orgCol[N];
  8. vector<int> adj[N];
  9.  
  10. int CountChild[N], par[N], num;
  11. vector<int> vec[N];
  12.  
  13. void DFS(int dad, int u) {
  14.     CountChild[u] = 1; par[u] = dad;
  15.     for (int v : adj[u]) if (v != dad) {
  16.         DFS(u, v);
  17.         CountChild[u] += CountChild[v];
  18.     }
  19. }
  20.  
  21. bool mark[N];
  22. int root[N];
  23.  
  24. void DFS2(int dad, int u) {
  25.     vec[num].push_back(u); mark[u] = true;
  26.     for (int v : adj[u]) if (v != dad) DFS2(u, v);
  27. }
  28.  
  29. int cutPoint = -1;
  30.  
  31. void prepare() {
  32.     DFS(0, 1);
  33.  
  34.     for (int u = 1; u <= n; ++u) {
  35.         bool ok = true;
  36.         for (int v : adj[u]) {
  37.             if (v == par[u] && n - CountChild[u] > n/2) { ok = false; break; }
  38.             if (v != par[u] && CountChild[v] > n/2) { ok = false; break; }
  39.         }
  40.         if (ok) { cutPoint = u; mark[u] = true; break; }
  41.     }
  42.  
  43.     for (int v : adj[cutPoint]) {
  44.         if (par[v] == cutPoint) {
  45.             ++num; DFS2(cutPoint, v);
  46.             root[num] = v;
  47.         }
  48.     }
  49.    
  50.     root[++num] = par[cutPoint];
  51.     for (int u = 1; u <= n; ++u) if (!mark[u]) vec[num].push_back(u), mark[u] = true;
  52.     if (vec[num].empty()) --num;
  53. }
  54.  
  55. vector<int> ls;
  56. int belong[N];
  57. int type0[N], type1[N], save0[N], save1[N];
  58.  
  59. bool BIT(int n, int k) { return n & (1<<k); }
  60.  
  61. void calc(int id) {
  62.     ls = vec[id]; int sz = ls.size();
  63.  
  64.     for (int mask = 0; mask < (1<<sz); ++mask) {
  65.         for (int i = 0; i < sz; ++i) col[ls[i]] = orgCol[ls[i]];
  66.        
  67.         int step = 0, ok = 0;
  68.         for (int i = 0; i < sz; ++i) if (BIT(mask, i)) {
  69.             ++step; int u = ls[i];
  70.             if (u == root[id]) ok = 1;
  71.             for (int v : adj[u]) if (belong[v] == id) col[v] = 1 - col[v];
  72.             col[u] = 1 - col[u];
  73.         }
  74.  
  75.         for (int u : ls) if (col[u] == 1) { step = -1; break; }
  76.         if (step == -1) continue;  
  77.  
  78.         if (!ok && type0[id] > step) { type0[id] = step; save0[id] = mask; }
  79.         if ( ok && type1[id] > step) { type1[id] = step; save1[id] = mask; }
  80.     }
  81. }
  82.  
  83. int res;
  84. bool cc;
  85. vector<ii> ans, diff, tmpAns;
  86.  
  87. void process(int Add) {
  88.     for (int i = 1; i <= num; ++i) type0[i] = type1[i] = oo, save0[i] = save1[i] = -1;
  89.     for (int i = 1; i <= num; ++i) {
  90.         calc(i);
  91.         if (type0[i] == oo && type1[i] == oo) return;
  92.     }
  93.  
  94.     int tmpRes = 0; tmpAns.clear(); col[cutPoint] = orgCol[cutPoint];
  95.     for (int i = 1; i <= num; ++i) {
  96.             //assert(type1[i] != oo || type0[i] != oo);
  97.         if (type1[i] == oo) tmpRes += type0[i], tmpAns.push_back(ii(save0[i], i));
  98.         if (type0[i] == oo) {
  99.             tmpRes += type1[i], tmpAns.push_back(ii(save1[i], i));
  100.             col[cutPoint] = 1 - col[cutPoint];
  101.         }
  102.     }
  103.  
  104.     diff.clear();
  105.     for (int i = 1; i <= num; ++i) if (type1[i] != oo && type0[i] != oo)
  106.         diff.push_back(ii(type1[i] - type0[i], i));
  107.  
  108.     int l = 0, r = 0;
  109.     while (r < (int) diff.size() && diff[r].first <= 0) ++r; --r;
  110.  
  111.     if (col[cutPoint] == 0) {
  112.         if ( (r - l + 1) % 2 == 1 ) --r;
  113.         for (int i = l; i <= r; ++i) {
  114.             tmpRes += type1[diff[i].second];
  115.             tmpAns.push_back(ii(save1[diff[i].second], diff[i].second));
  116.         }
  117.         for (int i = r+1; i < (int) diff.size(); ++i) {
  118.             tmpRes += type0[diff[i].second];
  119.             tmpAns.push_back(ii(save0[diff[i].second], diff[i].second));
  120.         }
  121.     }
  122.     else {
  123.         if ( (r - l + 1) % 2 == 0 ) --r;
  124.         if (l > r) ++r;
  125.         for (int i = l; i <= r; ++i) {
  126.             tmpRes += type1[diff[i].second];
  127.             tmpAns.push_back(ii(save1[diff[i].second], diff[i].second));
  128.         }
  129.         for (int i = r+1; i < (int) diff.size(); ++i) {
  130.             tmpRes += type0[diff[i].second];
  131.             tmpAns.push_back(ii(save0[diff[i].second], diff[i].second));
  132.         }
  133.     }
  134.  
  135.     if (res > tmpRes + Add) {
  136.         res = tmpRes + Add;
  137.         ans = tmpAns;
  138.         if (Add == 1) cc = true;
  139.         else cc = false;
  140.     }
  141. }
  142.  
  143. void sol() {
  144.     for (int i = 1; i <= num; ++i) for (int u : vec[i]) belong[u] = i;
  145.  
  146.     res = oo; ans.clear(); cc = false;
  147.    
  148.     /// not change cutPoint
  149.     process(0);
  150.  
  151.     /// change cutPoint
  152.     for (int v : adj[cutPoint]) orgCol[v] = 1 - orgCol[v]; orgCol[cutPoint] = 1 - orgCol[cutPoint];
  153.     process(1);
  154.  
  155.     /// Print
  156.     if (res == oo) { cout << -1 << '\n'; return; }
  157.  
  158.     cout << res << " ";
  159.     if (cc) cout << cutPoint << " ";
  160.     for (int i = 0; i < (int) tmpAns.size(); ++i) {
  161.         int id = tmpAns[i].second, mask = tmpAns[i].first;
  162.         for (int bit = 0; bit < (int) vec[id].size(); ++bit) if (BIT(mask, bit)) {
  163.             cout << vec[id][bit] << " ";
  164.         }
  165.     }
  166.     cout << '\n';
  167. }
  168.  
  169. int main() {
  170.     ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  171.     freopen("LAMPS.inp", "r", stdin);
  172.     freopen("LAMPS.out", "w", stdout);
  173.  
  174.     cin >> n >> T;
  175.     int u, v;
  176.     for (int i = 1; i < n; ++i) {
  177.         cin >> u >> v;
  178.         adj[u].push_back(v); adj[v].push_back(u);
  179.     }
  180.  
  181.     prepare();
  182.  
  183.     while (T--) {
  184.         for (int i = 1; i <= n; ++i) cin >> orgCol[i], orgCol[i] = 1 - orgCol[i];
  185.  
  186.         sol();
  187.     }
  188.  
  189.     return 0;
  190. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement