Pagini recente » Cod sursa (job #791999) | Cod sursa (job #164182) | Cod sursa (job #688358) | Cod sursa (job #1833139) | Cod sursa (job #1671135)
#include <bits/stdc++.h>
using namespace std;
#ifdef INFOARENA
#define cout fout
#endif // INFOARENA
ifstream fin("sakura.in");
ofstream fout("sakura.out");
/// ////////////////////////////////
#define nmax 502
int dp[nmax][nmax],L[nmax],R[nmax];
bool open[nmax];
vector<int> G[nmax];
class copacel
{
public:
vector<int> at_lev[nmax],G[nmax];
int lev[nmax],n,sz[nmax];
void grow()
{
int i,x,y;
fin>>n;
for(i=0; i<n; ++i) G[i].clear(),at_lev[i].clear(),lev[i]=0,sz[i]=0;
for(i=1; i<n; ++i)
{
fin>>x>>y;
G[x].push_back(y);
G[y].push_back(x);
}
}
void bloom(int nod)
{
at_lev[lev[nod]].push_back(nod);
sz[nod]=1;
for(auto son:G[nod])
{
if(sz[son]) continue;
lev[son]=lev[nod]+1;
bloom(son);
sz[nod]+=sz[son];
}
}
} brad,mar;
bool cupleaza(int nod)
{
if(open[nod]) return 0;
for(auto vec:G[nod])
if(L[vec]==-1)
{
L[vec]=nod;
R[nod]=vec;
return 1;
}
open[nod]=true;
for(auto vec:G[nod])
if(cupleaza(L[vec]))
{
L[vec]=nod;
R[nod]=vec;
open[nod]=false;
return 1;
}
open[nod]=false;
return 0;
}
bool try_match(int x,int y)
{
if(mar.G[y].size()==1 && y) return 1;
//if(brad.G[x].size() <mar.G[y].size()) return 0;
for(auto sonX:brad.G[x]) R[sonX]=-1,open[sonX]=0;
for(auto sonY:mar.G[y]) L[sonY]=-1;
for(auto sonX:brad.G[x])
if(R[sonX]==-1)
cupleaza(sonX);
int nr=(x!=0);
for(auto sonX:brad.G[x])
if(R[sonX]!=-1) ++nr;
return nr==mar.G[y].size();
}
void make_din()
{
if(brad.n<mar.n)
{
dp[0][0]=0;
return;
}
memset(dp,0,sizeof dp);
for(int i=0;i<brad.n;++i) G[i].clear();
for(int i=mar.n-1;i>=0;--i)
for(auto x:brad.at_lev[i])
for(auto y:mar.at_lev[i])
if(brad.sz[x]>=mar.sz[y])
{
dp[x][y]=try_match(x,y);
if(dp[x][y]) G[x].push_back(y);
}
}
int main()
{
int T;
fin>>T;
for(; T; --T)
{
brad.grow();
mar.grow();
brad.bloom(0);
mar.bloom(0);
make_din();
if(dp[0][0]) cout<<brad.n-mar.n<<'\n';
else cout<<"-1\n";
}
return 0;
}