Cod sursa(job #2791860)

Utilizator stefantagaTaga Stefan stefantaga Data 31 octombrie 2021 11:50:54
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.87 kb
#include <bits/stdc++.h>

using namespace std;
ifstream f("sakura.in");
ofstream g("sakura.out");
int mar[505];
vector <int> v[505],gr[505];
int mar2[505],tata1[505],tata2[505];
void dfs(int x,int tata)
{
    mar[x]=1;
    tata1[x]=tata;
    for (int i=0;i<v[x].size();i++)
    {
        if (v[x][i]!=tata)
        {
            dfs(v[x][i],x);
            mar[x]+=mar[v[x][i]];
        }
    }
}
void dfs2(int x,int tata)
{
    mar2[x]=1;
    tata2[x]=tata;
    for (int i=0;i<gr[x].size();i++)
    {
        if (gr[x][i]!=tata)
        {
            dfs2(gr[x][i],x);
            mar2[x]+=mar2[v[x][i]];
        }
    }
}
vector <int> cuplaj[505];
bool din[505][505];
int dreapta[505],sel[505];
bool cupleaza(int x)
{
    sel[x]=1;
    for (int i=0;i<cuplaj[x].size();i++)
    {
        if (dreapta[cuplaj[x][i]]==0)
        {
            dreapta[cuplaj[x][i]]=1;
            return 1;
        }
    }
    for (int i=0;i<cuplaj[x].size();i++)
    {
        if (sel[dreapta[cuplaj[x][i]]]==0&&cupleaza(dreapta[cuplaj[x][i]])==1)
        {
            sel[dreapta[cuplaj[x][i]]]=1;
            dreapta[cuplaj[x][i]]=x;
            return 1;
        }
    }
    return 0;
}
int m,cuplat[505];
void solve (int x,int tata)
{
    for (int i=0;i<v[x].size();i++)
    {
        if (v[x][i]!=tata)
        {
            solve(v[x][i],x);
        }
    }
    if (mar[x]==1)
    {
        int j;
        for (j=1;j<=m;j++)
        {
            if (mar2[j]==1)
            {
                din[x][j]=1;
            }
        }
    }
    else
    {
        int j,t,k;
        for (j=1;j<=m;j++)
        {
            if (mar[x]>=mar2[j])
            {
                for (t=1;t<=m;t++)
                {
                    cuplaj[t].clear();
                }
                for (k=0;k<v[x].size();k++)
                {
                    for (t=0;t<gr[j].size();t++)
                    {
                        if (din[gr[j][t]][v[x][k]]==1)
                        {
                            cuplaj[gr[j][t]].push_back(v[x][k]);
                        }
                    }
                }
                bool ok=1;
                int n1=gr[j].size();
                for (t=1;t<=n1;t++)
                {
                    cuplat[gr[j][t-1]]=0;
                }
                for (k=0;k<v[x].size();k++)
                {
                    dreapta[v[x][k]]=0;
                }
                while (ok==1)
                {
                    ok=0;
                    for (t=1;t<=n1;t++)
                    {
                        sel[gr[j][t-1]]=0;
                    }
                    for (t=1;t<=n1;t++)
                    {
                        if (cuplat[gr[j][t-1]]==0&&sel[gr[j][t-1]]==0)
                        {
                            ok=ok|cupleaza(gr[j][t-1]);
                        }
                    }
                }
                int sum=0;
                for (t=1;t<=n1;t++)
                {
                    if (cuplat[gr[j][t-1]]==1)
                    {
                        sum=sum+1;
                    }
                }
                if (sum==n1)
                {
                    din[x][j]=1;
                }
            }
        }
    }
}
int t,n,i,x,y;
int main()
{
    f>>t;
    for (;t--;)
    {
        f>>n;
        for (i=1;i<=n;i++)
        {
            v[i].clear();
        }
        for (i=1;i<=n-1;i++)
        {
            f>>x>>y;
            x++;
            y++;
            v[x].push_back(y);
            v[y].push_back(x);
        }
        f>>m;
        for (i=1;i<=m;i++)
        {
            gr[i].clear();
        }
        for (i=1;i<=m-1;i++)
        {
            f>>x>>y;
            x++;
            y++;
            gr[x].push_back(y);
            gr[y].push_back(x);
        }
        if (n<m)
        {
            g<<"-1"<<'\n';
            return 0;
        }
        for (i=1;i<=n;i++)
        {
            for (int j=1;j<=m;j++)
            {
                din[i][j]=0;
            }
        }
        dfs(1,0);
        dfs2(1,0);
        int j;
        for (i=1;i<=n;i++)
        {
            for (j=0;j<v[i].size();j++)
            {
                if (v[i][j]==tata1[i])
                {
                    v[i].erase(v[i].begin()+j);
                    break;
                }
            }
        }
        for (i=1;i<=m;i++)
        {
            for (j=0;j<gr[i].size();j++)
            {
                if (gr[i][j]!=tata2[i])
                {
                    gr[i].erase(gr[i].begin()+j);
                }
            }
        }
        solve(1,0);
        if (din[1][1]==1)
        {
            g<<n-m<<'\n';
        }
        else
        {
            g<<"-1"<<'\n';
        }
    }
    return 0;
}