Minimum Cost for Transportation Design

/*
Time limit: 1000ms
Memory limit: 256mb

---------------------Copy the following code, complete it and submit---------------------
I, <Your Full Name>, am submitting the assignment for
an individual project.
I declare that the assignment here submitted is original except for
source material explicitly acknowledged, the piece of work, or a part
of the piece of work has not been submitted for more than one purpose
(i.e. to satisfy the requirements in two different courses) without
declaration. I also acknowledge that I am aware of University policy
and regulations on honesty in academic work, and of the disciplinary
guidelines and procedures applicable to breaches of such policy and
regulations, as contained in the University website
http://www.cuhk.edu.hk/policy/academichonesty/.
It is also understood that assignments without a properly signed
declaration by the student concerned will not be graded by the
teacher(s).
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>
#include <string.h>

#define MAX_COST 999999
#define MAX_NODES 100000

// min heap

struct node {
    int id;
    int cost;
};

typedef struct node* Node;

struct Heap {
    int capacity;
    int size;
    Node* arr;
};

typedef struct Heap* HeapADT;

Node CreateHeapNode(int id, int cost) {
    Node tmp = (Node) malloc(sizeof(struct node));
    tmp->id = id;
    tmp->cost = cost;
    return tmp;
}

HeapADT CreateHeap(int capacity) {
    HeapADT heap = (HeapADT) malloc(sizeof(struct Heap));
    heap->capacity = capacity;
    heap->size = 0;
    heap->arr = (Node*) malloc((capacity + 1) * sizeof(Node));

    return heap;
}

void InsertHeap(HeapADT heap, Node tmp) {
    if (heap->size < heap->capacity) {
        heap->size++;

        int cur = heap->size;
        int father = cur / 2;
        while (father >= 1 && heap->arr[father]->cost > tmp->cost) {
            heap->arr[cur] = heap->arr[father];
            cur = father;
            father = cur / 2;
        }

        heap->arr[cur] = tmp;
    }
}

void DeleteHeap(HeapADT heap) {
    if (heap->size != 0) {
        Node tmp = heap->arr[heap->size];
        heap->size--;

        int cur = 1;
        int child = cur * 2;

        while (child <= heap->size) {
            if (child + 1 <= heap->size && heap->arr[child+1]->cost < heap->arr[child]->cost) {
                child++;
            }

            if (heap->arr[child]->cost < tmp->cost) {
                heap->arr[cur] = heap->arr[child];
                cur = child;
                child = cur * 2;
            } else {
                break;
            }
        }

        heap->arr[cur] = tmp;
    }
}

Node Top(HeapADT heap) {
    if (heap->size > 0) {
        return heap->arr[1];
    } else {
        return NULL;
    }
}

int Empty(HeapADT heap) {
    if (heap->size > 0) {
        return 0;
    } else {
        return 1;
    }
}

struct linkedListNode {
    int id;
    int weight;
    struct linkedListNode* next;
};

typedef struct linkedListNode* ListNode;

ListNode CreateListNode(int id, int weight) {
    ListNode node = (ListNode) malloc(sizeof(struct linkedListNode));
    node->id = id;
    node->weight = weight;
    node->next = NULL;

    return node;
}

// Graph ADT
struct graph {
    int n;
    ListNode* G;
};

typedef struct graph* GraphADT;

GraphADT CreateGraph(int n) {
    GraphADT myGraph = (GraphADT) malloc(sizeof(struct graph));
    myGraph->n = n;
    myGraph->G = (ListNode*) malloc(n * sizeof(ListNode));
    memset(myGraph->G, 0, n * sizeof(ListNode));

    return myGraph;
}

// Be careful: the graph is undirected
// So you need to add edge(u, v) and edge(v, u) at the same time
void AddEdge(GraphADT myGraph, int u, int v, int weight) {
    // WRITE YOUR CODE HERE

}


int cost[MAX_NODES+5];

// Tips: Use array cost[] to compute the weight of edge(u, v)
int Compute_Cost(int u, int v)
{
    // WRITE YOUR CODE HERE

}

// graph related data structure
int c[MAX_NODES+5];
int color[MAX_NODES+5];
// color 0 means the node is already in the spanning tree
// color 1 means the node is not yet in the spanning tree


long long Minimum_Spanning_Tree_Cost(GraphADT myGraph, int n, int m)
{
    HeapADT myHeap = CreateHeap(n + m * 2);
    for(int i = 0; i < myGraph->n; ++i) {
        c[i] = MAX_COST;
        color[i] = 0;
    }
    
    // Be careful: you need a long long variable to store the total cost
    // WRITE YOUR CODE HERE

}


int main() 
{
    int n, m, u, v;
    scanf("%d %d", &n, &m);
    GraphADT myGraph = CreateGraph(n);

    for(int i = 0; i < n; ++i)
        scanf("%d", &cost[i]);

    for(int i = 0; i < m; ++i)
    {
        scanf("%d %d", &u, &v);
        AddEdge(myGraph, u, v, Compute_Cost(u, v));
    }

    printf("%lld\n", Minimum_Spanning_Tree_Cost(myGraph, n, m));

	return 0;
}


---------------------------------------End of Code---------------------------------------

## [Minimum Cost for Transportation Design]

You are a renowned urban transportation designer tasked with designing a cost-effective transportation network for a country. 

The country is modeled as an undirected graph consisting of $n$ nodes (cities) with no initial roads (edges). 

The government has provided $m$ candidate roads for you, each represented as an undirected edge connecting two distinct cities. 

Your objective is to select exactly $n - 1$ roads from these candidates to form a connected undirected graph (a spanning tree) that minimizes the total construction cost.

Each city $i$ has a development coefficient $c_i$ , reflecting its level of infrastructure readiness.

The total cost of the network is calculated as the sum of $c_i × d_i$ for all cities, where $d_i$ denotes the degree of city $i$ in the chosen spanning tree.

Your challenge is to determine the optimal spanning tree configuration that minimizes this total cost. 

The provided candidate roads guarantee at least one valid solution exists.

Hint: The problem can be transformed into a minimum spanning tree (MST) problem by strategically assigning weights to edges. 

Consider how the development coefficients of connected cities influence the cost, and derive edge weights that allow standard MST algorithms (e.g., Krusky's or Prim's) to yield the optimal solution.

### Input

The first line contains two integers $n, m(1\leq n \leq m\leq 200000)$, representing the number of nodes and candidates roads.

The second line contains $n$ integers, and the $i$-th represents $c_{i-1} (1\leq c_{i-1}\leq 100000)$.

The next $m$ lines each contain two integers $u,v$, representing a candidate road.

### Output

Output one single integer, the minimum cost.

### Example
**Input**
```
5 6
1 4 5 1 5 
2 4
0 4
3 4
1 4
0 2
1 2
```

**Output**
```
27
```


Submit