Проблема конкурентного кодирования. BFS неориентированного графа. Получение WA - PullRequest
0 голосов
/ 21 апреля 2020

Я реализую алгоритм графа на Hackerrank .
Постановка задачи :
Правитель HackerLand считает, что каждый гражданин страны должен иметь доступ к библиотеке. К сожалению, HackerLand был поражен торнадо, который разрушил все его библиотеки и преградил ему дороги! Поскольку вы - величайший программист HackerLand, правитель хочет, чтобы вы помогли починить дороги и эффективно построить несколько новых библиотек.
HackerLand имеет n городов, пронумерованных от 1 до n. Города соединены двунаправленными дорогами. Гражданин имеет доступ к библиотеке, если:

  1. В их городе есть библиотека.
  2. Они могут путешествовать по дороге из своего города в город, содержащий библиотеку.

На следующем рисунке приведен пример карты HackerLand, где пунктирными линиями обозначены загороженные дороги:

Test case
Стоимость ремонта любой дороги составляет c_road долларов, а стоимость строительства библиотеки в любом городе составляет c_lib долларов. Если в приведенном выше примере c_road=2 и c_lib=3, мы построим 5 дорог по стоимости 5*2 и 2 библиотек по стоимости 6. Нам не нужно перестраивать одну из дорог в цикле 1->2->3->1.
Вам дано q запросов, где каждый запрос состоит из карты HackerLand и значения c_lib и c_road. Для каждого запроса найдите минимальную стоимость доступа к библиотекам для всех граждан и напечатайте ее на новой строке.

Мой подход:
Я делаю график с указанными городами и дорогами, где каждый город обозначает узел на графике, а каждая дорога обозначает ребро. Я использовал алгоритм BFS, чтобы найти связанные компоненты графа. Затем создайте библиотеку в каждом компоненте и постройте минимальное количество дорог, чтобы компоненты оставались подключенными.


Ответ:
Возврат минимум двух.

  1. Стоимость создания библиотеки в каждом компоненте + ремонт дорог, чтобы каждый компонент имел минимальное количество дорог.
  2. Создание библиотеки в каждом городе.
    В приведенном выше случае стоимость строительства дороги составляет 2 доллара (c_road=2), а стоимость создания библиотеки - 3 (c_lib=3).


    Здесь этот график состоит из двух компонентов:
  3. 1,2,3,7 (требуется дорога 3)
  4. 5,6,8 (дорога требуется 2)

Стоимость создания библиотеки в каждом компоненте (2*3=6) + стоимость строительства требуемой дороги (5*2=10) = 16
Стоимость создания библиотеки в каждом узле (7*3=21) = 21
Итак, 16 - это ответ.

Мой код:
Примечание: 1 индексация графика, используемого в этой программе.

#include<bits/stdc++.h>
using namespace std;

class Graph{
    int v; // number of vertices
    vector<int>*adj;
    public:

        Graph(int V){
            this->v=V+1;
            this->adj=new vector<int>[this->v];
        }

        void addEdge(int u,int v,bool biDir=true){
            adj[u].push_back(v);
            if(biDir)
                adj[v].push_back(u);
        }

        void bfs(int ar[]){
             // create a array of boolean to keep track of visited nodes.
             int numComponent=0,numEdge=0;
            bool visited[this->v];
            for(int i=1;i<this->v;i++)
                visited[i]=false;
            // for each node in graph
            for(int i=1;i<this->v;i++){
                if(!visited[i]){
                    numComponent++;
                    numEdge+=bfsUtill(i,visited);
                }

            }
            ar[0]=numComponent;
            ar[1]=numEdge;
        }

        int bfsUtill(int src, bool visited[]){
            // make a queue and insert src into it
            int numEdge=0;
            queue<int>q;
            q.push(src); // insert src into queue
            // mark first node as visited
            visited[src]=true;
            while(!q.empty()){
                int node=q.front();
                // visit
                cout<<node<<" ";
                // remove this node from queue
                q.pop(); 
                // visit every node adjacent to node 'node' 
                // if that node not visited then visit and enque it.
                for(int adjNode:adj[node]){
                    if(!visited[adjNode]){
                        numEdge++;
                        visited[adjNode]=true;
                        q.push(adjNode);
                    }
                }
            }
            return numEdge;
        }
};

// Complete the roadsAndLibraries function below.

long roadsAndLibraries(int n, int c_lib, int c_road, vector<vector<int>> cities) {
// if c_road is greater than c_lib then
if (c_road>c_lib){
    return n*c_lib;
}
Graph g(n);
// make graph of given vertices
for(auto x:cities)
    g.addEdge(x[0],x[1]);

// Array to store number of component and number of edges need to be repaired
int ar[2];
g.bfs(ar); 

long long int  libInEach=n*c_lib;
long long int roadAlso= ar[0]*c_lib+(ar[1]*c_road);

return min(libInEach,roadAlso);
}
// driver code
int main(){
    int t,n,m,c_lib,c_road;
    vector<vector<int>>cities;
    vector<int>temp;
    cin>>t;
    while(t--){
        cin>>n,m,c_lib,c_road;
        int a,b;
        for(int i=0;i<m;i++){
            cin>>a>>b;
            temp.push_back(a,b);
            cities.push_back(temp);
            temp.erase();
        }
        cout<<roadsAndLibraries(n,c_lib,c_road,cities);
    }
    return 0;
}

Я получаю правильный ответ для некоторых тестовых случаев и неправильный для некоторых тестовых случаев.
Я разместил только требуемый код, вставленный из всей программы. Ввод передается в эту функцию roadsAndLibraries().
Я проверяю вспомогательные функции, и они работают нормально.

- bfs()
- bfsUtill()
Контрольные примеры:

2
3 3 2 1
1 2
3 1
2 3
6 6 2 5
1 3
3 4
2 4
1 2
2 3
5 

Выходные данные для этого теста:

4
12

1 Ответ

2 голосов
/ 22 апреля 2020

Я отредактировал твой код. Это может работать для ваших тестовых случаев на хакерранке. Это работает нормально на данных тестовых примерах. В любом компоненте, если общее число вершин равно n, тогда минимальное число ребер, которые могут представлять один и тот же связанный компонент, равно n-1.

#include<bits/stdc++.h>
using namespace std;

class Graph{
    int v; // number of vertices
    vector<int>*adj;
    public:

        Graph(int V){
            this->v=V+1;
            this->adj=new vector<int>[this->v];
        }

        void addEdge(int u,int v,bool biDir=true){
            adj[u].push_back(v);
            if(biDir)
                adj[v].push_back(u);
        }

        void bfs(int ar[]){
             // create a array of boolean to keep track of visited nodes.
             int numComponent=0,numEdge=0;
            bool visited[this->v];
            for(int i=1;i<this->v;i++)
                visited[i]=false;
            // for each node in graph
            for(int i=1;i<this->v;i++){
                if(!visited[i]){
                    numComponent++;
                    numEdge+=bfsUtill(i,visited);
                }

            }
            ar[0]=numComponent;
            ar[1]=numEdge;
        }

        int bfsUtill(int src, bool visited[]){
            // make a queue and insert src into it
            int numEdge=1;
            queue<int>q;
            q.push(src); // insert src into queue
            // mark first node as visited
            visited[src]=true;
            while(!q.empty()){
                int node=q.front();
                // visit
                cout<<node<<" ";
                // remove this node from queue
                q.pop(); 
                // visit every node adjacent to node 'node' 
                // if that node not visited then visit and enque it.
                for(int adjNode:adj[node]){
                    if(!visited[adjNode]){
                        numEdge++;
                        visited[adjNode]=true;
                        q.push(adjNode);
                    }
                }
            }
            return numEdge-1;
        }
};

// Complete the roadsAndLibraries function below.

long roadsAndLibraries(int n, int c_lib, int c_road, vector<vector<int>> cities) {
// if c_road is greater than c_lib then
if (c_road>c_lib){
    return n*c_lib;
}
Graph g(n);
// make graph of given vertices
for(auto x:cities)
    g.addEdge(x[0],x[1]);

// Array to store number of component and number of edges need to be repaired
int ar[2];
g.bfs(ar); 

long long int  libInEach=n*c_lib;
long long int roadAlso= ar[0]*c_lib+(ar[1]*c_road);

return min(libInEach,roadAlso);
}
// driver code
int main(){
    int t,n,m,c_lib,c_road;
    vector<vector<int>>cities;
    vector<int>temp;
    cin>>t;
    while(t--){
        cin>>n,m,c_lib,c_road;
        int a,b;
        for(int i=0;i<m;i++){
            cin>>a>>b;
            temp.push_back(a,b);
            cities.push_back(temp);
            temp.erase();
        }
        cout<<roadsAndLibraries(n,c_lib,c_road,cities);
    }
    return 0;
}
...