Esempio n. 1
0
    // a *standard* implementation of Dijkstra's algorithm using a priority queue
    // with a minor modification for the problem
    static int GetTreeWeight(Graph graph, int hospital, int verticeCount, IEnumerable<int> hospitals)
    {
        var distances = new MinHeap<int>();

        foreach (var adj in graph[hospital])
        {
            distances.TrySetPriority(adj.Item2, adj.Item1);
        }

        // return value
        int ret = 0;

        var tree = new HashSet<int>();
        int housesAdded = 0;
        int totalHouses = verticeCount - hospitals.Count();

        while (housesAdded < totalHouses && distances.Count > 0)
        {
            // edge nearest to 'hospital'

            var min = distances.ChopHeadWithPriority();
            var weight = min.Item1;

            // the new vertex in the tree

            var v1 = min.Item2;

            // modification of algorithm:
            // sum the distance to the root of all nodes that aren't
            // hospitals

            if (!hospitals.Contains(v1))
            {
                housesAdded += 1;
                ret += weight;
            }

            tree.Add(v1);

            // update the priorities of all external neighbours of the vertex
            // we've just added

            foreach (var adj in graph[v1])
            {
                var v2 = adj.Item1;
                if (v2 == hospital)
                    continue;
                if (tree.Contains(v2))
                {
                    continue;
                }

                // perhaps improve priority
                distances.TrySetPriority(weight + adj.Item2, v2, false);

            }
        }

        return ret;
    }