Advertisement
Mlxa

D второго дня

Jan 30th, 2019
1,090
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.65 KB | None | 0 0
  1. #define NDEBUG
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. #define long ll
  6. #define all(x) begin(x), end(x)
  7.  
  8. namespace flow {
  9.     const int SOURCE    = 2198;
  10.     const int SINK      = 2199;
  11.     const int N         = 2200;
  12.     const int INT_INF   = 0x3f3f3f3f;
  13.     int c[N][N];
  14.     int f[N][N];
  15.     int d[N];
  16.     int p[N];
  17.    
  18.     void add_edge(int a, int b, int w) {
  19.         c[a][b] += w;
  20.     }
  21.    
  22.     int lim;
  23.    
  24.     bool bfs() {
  25.         memset(d, 0x3f, sizeof d);
  26.         memset(p, 0, sizeof p);
  27.         d[SOURCE] = 0;
  28.         deque<int> q = { SOURCE };
  29.         while (q.size()) {
  30.             int v = q.front();
  31.             q.pop_front();
  32.             for (int u = 0; u < N; ++u) {
  33.                 if (c[v][u] - f[v][u] >= lim && d[u] > d[v] + 1) {
  34.                     d[u] = d[v] + 1;
  35.                     q.push_back(u);
  36.                 }
  37.             }
  38.         }
  39.         return d[SINK] < INT_INF;
  40.     }
  41.    
  42.     int dfs(int v, int min_c) {
  43.         if (v == SINK) {
  44.             return min_c;
  45.         }
  46.         for (; p[v] < N; ++p[v]) {
  47.             int u = p[v];
  48.             if (d[u] == d[v] + 1 && c[v][u] - f[v][u] >= lim) {
  49.                 int delta = dfs(u, min(min_c, c[v][u] - f[v][u]));
  50.                 if (delta > 0) {
  51.                     f[v][u] += delta;
  52.                     f[u][v] -= delta;
  53.                     return delta;
  54.                 }
  55.             }
  56.         }
  57.         return 0;
  58.     }
  59.    
  60.     void find_flow() {
  61.         int answer = 0;
  62.         for (lim = 1 << 20; lim > 0; lim /= 2) {
  63.             while (bfs()) {
  64.                 int cur_flow = dfs(SOURCE, INT_INF);
  65.                 while (cur_flow > 0) {
  66.                     answer += cur_flow;
  67.                     cur_flow = dfs(SOURCE, INT_INF);
  68.                 }
  69.             }
  70.         }
  71.         assert(answer >= 0);
  72.     }
  73. }
  74.  
  75. const int N     = 2e5 + 5;
  76. const int K     = 7;
  77. const int TK    = 2187;
  78.  
  79. int n, k;
  80. int a[N][K];
  81. int t[N][K];
  82. int d[TK][K];
  83. vector<int> bag[TK];
  84. vector<int> srt[K];
  85. int x2_med[K];
  86.  
  87. char good[3][3] = {
  88.     { 0, 1, 1 },
  89.     { 1, 1, 1 },
  90.     { 1, 1, 0 }
  91. };
  92.  
  93.  
  94.  
  95.  
  96.  
  97. int main() {
  98.     ios::sync_with_stdio(false);
  99.     cin.tie(nullptr);
  100.    
  101.     cin >> n >> k;
  102.     for (int i = 0; i < n; ++i) {
  103.         for (int j = 0; j < k; ++j) {
  104.             cin >> a[i][j];
  105.             srt[j].push_back(a[i][j]);
  106.         }
  107.     }
  108.     for (int i = 0; i < k; ++i) {
  109.         sort(all(srt[i]));
  110.         x2_med[i] = srt[i][n / 2 - 1] + srt[i][n / 2];
  111.     }
  112.     for (int i = 0; i < n; ++i) {
  113.         for (int j = 0; j < k; ++j) {
  114.             if (2 * a[i][j] < x2_med[j]) {
  115.                 t[i][j] = 0;
  116.             } else if (2 * a[i][j] == x2_med[j]) {
  117.                 t[i][j] = 1;
  118.             } else {
  119.                 t[i][j] = 2;
  120.             }
  121.         }
  122.         assert(t[i][0] != 1);
  123.         int id = 0;
  124.         for (int j = k - 1; j >= 0; --j) {
  125.             id = 3 * id + t[i][j];
  126.         }
  127.         bag[id].push_back(i);
  128.     }
  129.    
  130.     for (int i = 0; i < TK; ++i) {
  131.         int x = i;
  132.         for (int j = 0; j < k; ++j) {
  133.             d[i][j] = x % 3;
  134.             x /= 3;
  135.         }
  136.     }
  137.    
  138.     for (int i = 0; i < TK; ++i) {
  139.         if (bag[i].empty()) {
  140.             continue;
  141.         }
  142.         for (int j = i + 1; j < TK; ++j) {
  143.             if (bag[j].empty()) {
  144.                 continue;
  145.             }
  146.             bool br = false;
  147.             for (int bit = 0; bit < k; ++bit) {
  148.                 if (!good[d[i][bit]][d[j][bit]]) {
  149.                     br = true;
  150.                     break;
  151.                 }
  152.             }
  153.             if (br) {
  154.                 continue;
  155.             }
  156.             if (d[i][0] == 0) {
  157.                 assert(d[j][0] == 2);
  158.                 flow::add_edge(i, j, (int)1e9);
  159.             } else {
  160.                 assert(d[j][0] == 0);
  161.                 flow::add_edge(j, i, (int)1e9);
  162.             }
  163.         }
  164.     }
  165.    
  166.    
  167.     for (int i = 0; i < TK; ++i) {
  168.         if (bag[i].empty()) {
  169.             continue;
  170.         }
  171.         if (d[i][0] == 0) {
  172.             flow::add_edge(flow::SOURCE, i, (int)bag[i].size());
  173.         } else {
  174.             flow::add_edge(i, flow::SINK, (int)bag[i].size());
  175.         }
  176.     }
  177.    
  178.    
  179.     flow::find_flow();
  180.    
  181.     vector<pair<int, int>> answer;
  182.     for (int v = 0; v < TK; ++v) {
  183.         for (int u = 0; u < TK; ++u) {
  184.             while (flow::f[v][u]-- > 0) {
  185.                 answer.emplace_back(bag[v].back(), bag[u].back());
  186.                 bag[v].pop_back();
  187.                 bag[u].pop_back();
  188.             }
  189.         }
  190.     }
  191.    
  192.     if ((int)answer.size() == n / 2) {
  193.         cout << "YES\n";
  194.         for (auto &e : answer) {
  195.             cout << e.first + 1 << ' ' << e.second + 1 << '\n';
  196.         }
  197.     } else {
  198.         cout << "NO\n";
  199.     }
  200.    
  201.     return 0;
  202. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement