简体   繁体   中英

graph data structure in node js

update 1:

I found an example of BFS here https://medium.com/basecs/breaking-down-breadth-first-search-cebe696709d9 , but I am getting an error TypeError: Cannot read property 'left' of undefined . can you tell me how to fix it

function roadsAndLibraries(n, c_lib, c_road, cities) {
    console.log("roadsAndLibraries n--->", n);
    console.log("roadsAndLibraries c_lib--->", c_lib);
    console.log("roadsAndLibraries c_road--->", c_road);
    console.log("roadsAndLibraries cities--->", cities);
    var m = new Map();
    m.set('a', 2);
    m.set('b', 3);
    m.set('b', 3);
    m.set('b', 2);
    m.set('b', 1);

    console.log("map value--->", m);
        // Check that a root node exists.

    // if (rootNode === null) {
    //     return;
    // }

    // Check that a root node exists.
    if (n === null) {
        console.log("n root node--->", n);
        return;
    }

    // Create our queue and push our root node into it.
    // var queue = [];
    // queue.push(rootNode);

    // Create our queue and push our root node into it.
    var queue = [];
    queue.push(n);

    console.log(" queue.push--->", queue);


    while (queue.length > 0) {
        // Create a reference to currentNode, at the top of the queue.
        var currentNode = queue[0];

        // If currentNode has a left child node, add it to the queue.
        if (currentNode.left !== null) {
            queue.push(currentNode.left)
        }
        // If currentNode has a right child node, add it to the queue.
        if (currentNode.right !== null) {
            queue.push(currentNode.right)
        }
        // Remove the currentNode from the queue.
        queue.shift()
    }




}

graph code

'use strict';

const fs = require('fs');

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', function() {
    inputString = inputString.replace(/\s*$/, '')
        .split('\n')
        .map(str => str.replace(/\s*$/, ''));

    main();
});

function readLine() {
    return inputString[currentLine++];
}

// Complete the roadsAndLibraries function below.
function roadsAndLibraries(n, c_lib, c_road, cities) {
    console.log("roadsAndLibraries n--->", n);
    console.log("roadsAndLibraries c_lib--->", c_lib);
    console.log("roadsAndLibraries c_road--->", c_road);
    console.log("roadsAndLibraries cities--->", cities);

var m = new Map();
    m.set('a', 2);
    m.set('b', 3);
    m.set('b', 3);
    m.set('b', 2);
    m.set('b', 1);

    console.log("map value--->", m);





}

function main() {
    const ws = fs.createWriteStream(process.env.OUTPUT_PATH);
    console.log("ws--->", ws);


    const q = parseInt(readLine(), 10);
    console.log("q--->", q);

    for (let qItr = 0; qItr < q; qItr++) {
        const nmC_libC_road = readLine().split(' ');
        console.log("nmC_libC_road--->", nmC_libC_road);

        const n = parseInt(nmC_libC_road[0], 10);
        console.log("n--->", n);


        const m = parseInt(nmC_libC_road[1], 10);
        console.log("m--->", m);

        const c_lib = parseInt(nmC_libC_road[2], 10);
        console.log("c_lib--->", c_lib);

        const c_road = parseInt(nmC_libC_road[3], 10);
        console.log("c_road--->", c_road);

        let cities = Array(m);
        console.log("cities--->", cities);

        for (let i = 0; i < m; i++) {
            cities[i] = readLine().split(' ').map(citiesTemp => parseInt(citiesTemp, 10));
        }

        const result = roadsAndLibraries(n, c_lib, c_road, cities);
        console.log("result--->", result);

        ws.write(result + '\n');
    }

    ws.end();
}

sample output

ws---> WriteStream {
  _writableState:
   WritableState {
     objectMode: false,
     highWaterMark: 16384,
     finalCalled: false,
     needDrain: false,
     ending: false,
     ended: false,
     finished: false,
     destroyed: false,
     decodeStrings: true,
     defaultEncoding: 'utf8',
     length: 0,
     writing: false,
     corked: 0,
     sync: true,
     bufferProcessing: false,
     onwrite: [Function: bound onwrite],
     writecb: null,
     writelen: 0,
     bufferedRequest: null,
     lastBufferedRequest: null,
     pendingcb: 0,
     prefinished: false,
     errorEmitted: false,
     emitClose: false,
     bufferedRequestCount: 0,
     corkedRequestsFree:
      { next: null,
        entry: null,
        finish: [Function: bound onCorkedFinish] } },
  writable: true,
  _events: [Object: null prototype] {},
  _eventsCount: 0,
  _maxListeners: undefined,
  path:
   '/tmp/submission/20190610/18/32/hackerrank-e7eb8e7be2993c28875aad2bbb8d6292/0.userout',
  fd: null,
  flags: 'w',
  mode: 438,
  start: undefined,
  autoClose: true,
  pos: undefined,
  bytesWritten: 0,
  closed: false }
q---> 2
nmC_libC_road---> [ '3', '3', '2', '1' ]
n---> 3
m---> 3
c_lib---> 2
c_road---> 1
cities---> [ <3 empty items> ]
roadsAndLibraries n---> 3
roadsAndLibraries c_lib---> 2
roadsAndLibraries c_road---> 1
roadsAndLibraries cities---> [ [ 1, 2 ], [ 3, 1 ], [ 2, 3 ] ]
result---> undefined
nmC_libC_road---> [ '6', '6', '2', '5' ]
n---> 6
m---> 6
c_lib---> 2
c_road---> 5
cities---> [ <6 empty items> ]
roadsAndLibraries n---> 6
roadsAndLibraries c_lib---> 2
roadsAndLibraries c_road---> 5
roadsAndLibraries cities---> [ [ 1, 3 ], [ 3, 4 ], [ 2, 4 ], [ 1, 2 ], [ 2, 3 ], [ 5, 6 ] ]
result---> undefined

It seems to me as though you are having trouble understanding what the problem is about. I will try to summarize it and point out a few things you need to consider.

City graph

You are given a graph where each node is a city and an edge is a bidirectional road between two cities. This means you are dealing with an undirected graph, meaning if there is an edge(=road) between cities A and B, you can travel from A to B and from B to A. Of course you can represent this in terms of directed graph by creating two edges for each road: one from A to B and one from B to A. But I don't think this is necessary.

Now, you want every city to either have a library or have a path to a city with a library. You realize that if you have two sets of cities that are not linked by any road, you will need at least one library for each of these sets. Such sets of cities are called connected components of a graph . You will need to identify these components. They will be parts of the problem that have to be solved independently.

Cost of access to library

The second information you are given is the cost of rebuilding a library in a city and the price of repairing a road. As you are trying to minimize the total cost, this means that you are trying to rebuild as few roads a possible and as few libraries as possible.

You realize that if the cost of rebuilding a library is less than or equal to the cost of building a road , the cheaper option is to build a library at every city.

In other cases, the solution is fairly simple but not as easy to see. Let's consider a single connected component. For commodity, let's assume that cities A, B, C and D are the nodes of this connected component.

A----B
|    |
C----D

You already know you will need to place at least one library on one of the cities. Let's place a library on city A. Then, as we are in a connected component, A has some roads (minimum one, maximum 3) that go to other cities. For the cities that have a road that connects them to city A, it is cheaper to rebuild the road than to build a new library. So we choose to rebuild the road. Now city A and the neighbors of A (cities B and D) can access a library. Then, among the neighbors of A (cities B and C), there will be roads to cities that do not yet have access to a library. In this case, both C and B have a road to D. We will only need one road to connect D to the library in A. Again, it is cheaper to build a road to a city that can access to a library than to build a new library.

Algorithm

The previous method of gradually connecting cities by spreading to all neighbors of the first node, then the neighbors of the neighbors of the first nodes (recursively) is a BFS. As a bonus, the BFS algorithm is suitable for finding connected components of a graph.

If you understood the previous explanations, I think you are able to solve the problem. You can run a BFS algorithm on the graph. When you start the algorithm, count 1 library, and then 1 road each time you connect to a new city. When you finish your BFS algorithm but there are still cities in the graph that you have not visited, count an additional library and use BFS again starting from a city that you haven't explored yet.

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