Finding the smallest vertex cover in a tree

In one country called Infoland, there are n cities connected by two-way roads. A chain between cities a and b is a route between these cities that uses each road no more than once. Roads in this country are built so that for any cities a and b, there is exactly one chain connecting these two cities. The government of this country has adopted a decree on the control of the roads of its state. It was decided in some cities to create committees for the control of all roads that start or end in this city. In order to save money, it is necessary to create the smallest possible number of such committees, but that any road is under the control of at least one committee. In response, print the minimum number of cities.

My algorithm. It is obvious from the condition that these cities form a graph, and this graph will be a tree, then to find the minimum number of cities, you need to find its smallest vertex cover. That's where it starts problem. Finding the smallest vertex cover is an NP-complete problem. But if it were a bipartite graph, then the problem would be reduced to finding the maximum matching. Question: how can I reduce my graph to a bipartite graph, and is this even possible? Can my algorithm be considered correct? And if not, then how to solve this problem I bring the code in C++, crashes on most of the tests,how to fix or write better?

   #include<iostream>
#include<fstream>
#include<algorithm>
#include<vector>
#include<queue>
#include<iomanip>
#include <set> 
#pragma comment(linker, "/STACK:1677721600")
using namespace std;
int n;
vector <vector<int>> G1(n);
vector<vector<int>>K1(n);
vector<int>I(n);

int get_independent_set(int u)
{
    if (I[u] != 0)
        return I[u];
    else
    {
        int children_sum = 0;
        int grandchildren_sum = 0;
            // цикл по всем детям
        for (int i = 0; i < G1[u].size(); i++)
            children_sum = children_sum + get_independent_set(G1[u][i]);
                // цикл по всем внукам
        for (int i = 0; i < K1[u].size(); i++)
            grandchildren_sum = grandchildren_sum + get_independent_set(K1[u][i]);
                    // запоминаем, чтобы не пересчитывать ещё раз
        I[u] = max(1 + grandchildren_sum, children_sum);
        return I[u];
    }
}

int main()
{
    ifstream fin("input.txt");
    ofstream fout("output.txt");

    fin >> n;


    vector <vector<int>> G(n);
    vector<int>I1(n);
    int i, v, k = 0;

    while (fin >> i)
    {
        for (int j = 0; j < i; j++)
        {
            fin >> v;
            G[k].push_back(v-1);
        }
        k++;
    }
    vector<bool>used(n);
    queue<int>q1;
    queue<int> q;
    q.push(0);
    vector<vector<int>>child(n);
    vector<vector<int>>vnuki(n);
    while (!q.empty())
    {
        int m = q.front();
        q.pop();
        used[m] = true;

        for (int j = 0; j < G[m].size(); j++)
        {
            if (!(used[G[m][j]]))
            {
                child[m].push_back(G[m][j]);
                q.push(G[m][j]);
                for (int k = 0; k < G[G[m][j]].size(); k++)
                {
                    if (G[G[m][j]][k] != m)
                        vnuki[m].push_back(G[G[m][j]][k]);
                }
            }


        }

    }
    G1 = child;
    K1 = vnuki;
    I = I1;

    int ver = get_independent_set(0);
    fout << n - ver;
    return 0;
}
Author: Артём, 2018-10-11

2 answers

The complement to the vertex cover is the set of independent vertices, and the problem of the independent set for the tree is solved by dynamic programming.

The last algorithm in the wiki is described by

Cardinality of the set (either we take the root and the grandchildren, or all the children, otherwise some edge will be missed)

I(root) = max (1 + Sum{I(внуков)}, Sum{I(детей)})

The sets themselves can be obtained and written when the maximum is selected

 3
Author: MBo, 2018-10-11 15:52:30

A tree is an acyclic graph. Any acyclic graph is bipartite. The problem of finding the minimum vertex cover in a bipartite graph is easily and efficiently solved through the problem of the maximum matching in a bipartite graph (see Koenig's theorem).

The maximum matching in a bipartite graph is constructed by theHopcroft-Karp algorithm (or, alternatively, Ford-Fulkerson).

And this is even if you just consider a tree as a bipartite graph. But it is in this task can be solved even easier. Offhand: and just a greedy set of vertices of the maximum "uncovered" degree is not suitable here?

 2
Author: AnT, 2018-10-11 16:07:53