简体   繁体   中英

Problem of competitive coding. BFS of undirected graph. Getting WA

I am implementing graph algorithm on Hackerrank .
Problem statement :
The Ruler of HackerLand believes that every citizen of the country should have access to a library. Unfortunately, HackerLand was hit by a tornado that destroyed all of its libraries and obstructed its roads, As you are the greatest programmer of HackerLand. the ruler wants your help to repair the roads and build some new libraries efficiently.
HackerLand has n cities numbered from 1 to n. The cities are connected by m bidirectional roads. A citizen has access to a library if:

  1. Their city contains a library.
  2. They can travel by road from their city to a city containing a library.

The following figure is a sample map of HackerLand where the dotted lines denote obstructed roads:

测试用例
The cost of repairing any road is c_road dollars, and the cost to build a library in any city is c_lib dollars. If in the above example c_road=2 and c_lib=3 , we would build 5 roads at a cost of 5*2 and 2 libraries for a cost of 6 . We don't need to rebuild one of the roads in the cycle 1->2->3->1 .
You are given q queries, where each query consists of a map of HackerLand and value of c_lib and c_road . For each query, find the minimum cost of making libraries accessible to all the citizens and print it on a new line.

My approach:
I make a graph with the given cities and roads, where each city denotes a node in the graph and each road denotes a edge. I used BFS algorithm to find connected components of the graph. Then make a library in each component, and build minimum number of roads so that components remains connected.


Answer:
Rerurn the minimum of two.

  1. The cost of making a library in each component + repairing roads so that each component has minimum number of roads.
  2. Making a library in each city.
    In the above case cost of building a road is 2 dollars (c_road=2) and cost of making a library is 3 (c_lib=3) .


    Here, this graph has two components:
  3. 1,2,3,7 (road required is 3)
  4. 5,6,8 (road required is 2)

Cost of making a library in each component (2*3=6) + cost of buiding required road is (5*2=10) = 16
Cost of building a library in each node is (7*3=21) = 21
So, 16 is the answer.

My Code:
Note: 1 based indexing of graph used in this program.

#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;
}

I am getting correct answer for some test cases and incorrect for some test cases.
I posted only required code, insted of whole program. Input is passed into this function roadsAndLibraries() .
I test helper function and those are working fine.

- bfs()
- bfsUtill()
Test cases:

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 

Output for this test case:

4
12

I edited your code. This might work for your test cases on hackerrank. This is working fine on given test cases. In any component if totel number of vertices is n then minimum number of edges, that can represent the same connected component is 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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM