Cod sursa(job #2156606)

Utilizator retrogradLucian Bicsi retrograd Data 8 martie 2018 20:51:59
Problema Felinare Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.59 kb
#include <bits/stdc++.h>

using namespace std;

struct BipartiteMatcher {
  int n, m;
  vector<vector<int>> G;
  vector<int> L, R, vis;
  
  BipartiteMatcher(int n, int m) :
    n(n), m(m), G(n), L(n, -1), R(m, -1), vis(n) {}
  
  void AddEdge(int a, int b) {
    G[a].push_back(b);
  }
  
  bool match(int node) {
    if (vis[node])
      return false;
    vis[node] = true;
    
    for (auto vec : G[node]) {
      if (R[vec] == -1 || match(R[vec])) { // (*)
        L[node] = vec; R[vec] = node; return true;
      }
    }
    return false;
  }

  int Solve() {
    int ok = 1;
    while (ok--) {
      fill(vis.begin(), vis.end(), 0);
      for (int i = 0; i < n; ++i) // (**)
        if (L[i] == -1)
          ok |= match(i);
    }
    return n - count(L.begin(), L.end(), -1);
  }

  // Only include if you want vertex cover
  vector<bool> CL, CR;

  void cover(int node) {
    for (auto vec : G[node]) if (!CR[vec]) {
      CR[vec] = true; 
      CL[R[vec]] = false; 
      cover(R[vec]);
    }
  }

  int VertexCover() {
    int ret = Solve();
    CL.assign(n, false); CR.assign(m, false);
    for (int i = 0; i < n; ++i) if (L[i] != -1) CL[i] = true;
    for (int i = 0; i < n; ++i) if (L[i] == -1) cover(i);
    return ret;
  }
};

int main() {
    ifstream cin("felinare.in");
    ofstream cout("felinare.out");

    int n, m; cin >> n >> m;
    BipartiteMatcher bm(n, n);
    while (m--) {
      int a, b; cin >> a >> b;
      bm.AddEdge(a - 1, b - 1);
    }

    cout << 2 * n - bm.VertexCover() << endl;
    for (int i = 0; i < n; ++i) {
      cout << 2 * (!bm.CR[i]) + (!bm.CL[i]) << '\n';
    }
    return 0;
}