Cod sursa(job #2897798)

Utilizator PetyAlexandru Peticaru Pety Data 4 mai 2022 20:34:35
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.62 kb
#include <bits/stdc++.h>
#define ll long long

using namespace std;

const int INF = 1e9;
const int MOD = 1e9 + 7;

ifstream fin ("sakura.in");
ofstream fout ("sakura.out");


int t, n, m, sz[502], sz2[502], can[502][502], par[502], par2[502], viz[502], st[502], dr[502];
vector<int>G[502];
vector<int>G2[502];
vector<int>cuplaj[1002];

void dfs1 (int nod, int p) {
  sz[nod] = 1;
  par[nod] = p;
  for (auto it : G[nod])
    if (it != p) {
      dfs1(it, nod);
      sz[nod] += sz[it];
    }
}
void dfs2 (int nod, int p) {

  sz2[nod] = 1;
  par2[nod] = p;
  for (auto it : G2[nod])
    if (it != p) {
      dfs2(it, nod);
      sz2[nod] += sz2[it];
    }
}

bool match (int nod) {
  if (viz[nod])
    return 0;
  viz[nod] = 1;
  for (auto it : cuplaj[nod])
    if (!dr[it] || match(dr[it])) {
      st[nod] = it;
      dr[it] = nod;
      return 1;
    }
  return 0;
}

vector<int>son1;
vector<int>son2;

bool solve (int a, int b) {
  if (can[a][b] != -1)
    return can[a][b];
  if (sz[a] < sz2[b])
    return can[a][b] = 0;
  if (sz2[b] == 1)
    return can[a][b] = 1;
  vector<int>son1;
  vector<int>son2;
  for (auto it : G[a])
    if (it != par[a])
      son1.push_back(it);
  for (auto it : G2[b])
    if (it != par2[b])
      son2.push_back(it);
  for (auto it : son1)
    for (auto it2: son2)
     solve(it, it2);
  for (auto it : son1) {
    cuplaj[it].clear();
    st[it] = 0;
    for (auto it2 : son2)
      if (can[it][it2])
        cuplaj[it].push_back(it2);
    viz[it] = 0;
  }
  for (auto it : son2)
    dr[it] = 0; 
  do {
    bool ok = 0;
    for (auto it : son1)
      viz[it] = 0;
    for (auto it : son1) 
      if (!st[it] && match(it))
        ok = 1;
    if (!ok)
      break;
  }while (1);
  int nr = 0;
  for (auto it : son1)
    if (st[it])
      nr++;
  if (nr == son2.size())
    return can[a][b] = 1;
  else
    return can[a][b] = 0;
}

int main () 
{
  ios_base::sync_with_stdio(false);
  cin.tie(0); cout.tie(0);
  fin >> t;
  while (t--) {
    fin >> n;
    for (int i = 1; i < n; i++) {
      int x, y;
      fin >> x >> y;
      x++; y ++;
      G[x].push_back(y);
      G[y].push_back(x);
    }
    fin >> m;
    for (int i = 1; i < m; i++) {
      int x, y;
      fin >> x >> y;
      x++; y++;
      G2[x].push_back(y);
      G2[y].push_back(x);
    }
    for (int i = 1; i <= n; i++)
     for (int j = 1; j <= m; j++)
       can[i][j] = -1;
    dfs1(1, 0);
    dfs2(1, 0);
    solve(1, 1);
    if (can[1][1])
      fout << n - m;
    else
      fout << -1;
    fout << "\n";
    for (int i = 1; i <= n; i++) {
      G[i].clear();
      cuplaj[i].clear();
    }
    for (int i = 1; i <= m; i++) 
      G2[i].clear();
  }
  
  
  return 0;
}