-2

You have to construct a bridge in a city. Bridge consists of n sections (1 to n). There are m construction teams. The Ith team will work on the section from (li to ri) of the bridge. Bridge is said to be constructive if all sections from (1 to n) are worked on by at least one of the teams.

The cost of building a section is number of teams that worked on it, So the cost of building the bridge is the sum of the cost of cost of building all the sections.

Your task is to choose a subset of the teams such that bridge is completely constructed(i.e all the sections from (1 to n) is worked on by at least one of the team from this subset) and cost of building the bridge is the minimum possible. If it is not possible, print -1.

Examples: N=4 m=3; teams = [(1,2),(2,3),(3,4)]

Approach :

  1. The optimal way is to choose team 1 and team 3. 2) Sections 1 and 2 will be constructed by team 1 and sections 3 and 4 will be by team 3
  2. so cost of constructing the bridge will be 4, as each section is worked on exactly 1 team.

Hence answer is 4.

Please provide the efficient approach for this problem.

halfer
  • 19,824
  • 17
  • 99
  • 186
  • 1
    It looks like this is the same question as [this](https://stackoverflow.com/questions/68045387/how-to-cover-a-range-using-a-set-of-ranges-with-minimal-overlap). – גלעד ברקן Jun 19 '21 at 19:56

1 Answers1

-1

Here is the greedy algorithm - always the best place to start.

allocate all teams
IF not all sections covered
    output -1
    stop
mark all teams non-critical
flag_improved = true
WHILE( flag_improved == true )
   flag_improved = false
   find most expensive section 
   find most expensive non-critical team on most expensive section 
   IF team found that can be removed without leaving a section uncovered
       remove team
       flag_improved = true
   ELSE
       mark team critical
output cost - sum coverage of remaining teams

definitions:

  • most expensive section is one with most teams allocated to it
  • most expensive team is one that covers the most section

find most expensive non-critical team on most expensive section :

most_expense = 0
team
LOOP t over teams assigned to most expensive section
   IF team is critical
        continue
   IF team expense > most_expense
        most_expense = team expense
        team = t

Here is the main function of a C++ application implementing this algorithm

main()
{
    std::vector<cTeam> teams;
    int bridge_section_count;
    Input( bridge_section_count, teams);

    // allocate all teams
    for (int s = 0; s < bridge_section_count; s++)
        Bridge.insert(std::pair(s, std::vector<cTeam>(0)));
    for (auto &t : teams)
        for (int s = t.myRange.first; s <= t.myRange.second; s++)
        {
            Bridge[s].push_back(t);
        }

    // check every section has at least one team allocated
    if (!IsCovered())
    {
        std::cout << "-1\n";
        exit(1);
    }

    // loop while improvements are being found
    bool flag_improved = true;
    while (flag_improved)
    {
        flag_improved = false;

        auto most_expensive_section = find_most_expensive_section();

        while (1)
        {
            // loop over teams allocated to most expensive section
            std::vector<cTeam>::iterator most_expensive_team;
            if (!find_most_expensive_non_critical_team(
                    most_expensive_team,
                    most_expensive_section))
            {
                break;
            }

            // check can team be removed without leaving section uncovered
            if (testRemoval(*most_expensive_team))
            {
                // remove team
                doRemoval(*most_expensive_team);
                flag_improved = true;
                break;
            }
            else
            {
                // this team is critical, it cannot be removed
                most_expensive_team->myCritical = true;
            }
        }
    }
    printResult();
}

The complete application code is at https://gist.github.com/JamesBremner/ada6210a8517671abd45e882c97d526d

ravenspoint
  • 19,093
  • 6
  • 57
  • 103