// Sadonkorjuu2.cpp : Defines the entry point for the application.
//
#include "Sadonkorjuu2.h"
using namespace std;
#include <bits/stdc++.h>
vector<int> satamat;
vector<vector<int>> vaihtoehdot(200000, vector<int>(1000, 0));
vector<int> split(const string& str, char delimiter) {
vector<int> tokens;
string token;
istringstream tokenStream(str);
while (getline(tokenStream, token, delimiter)) {
tokens.push_back(stoi(token));
}
return tokens;
}
struct AdjListNode
{
int dest;
int weight;
struct AdjListNode* next;
};
struct AdjList
{
struct AdjListNode* head;
};
struct Graph
{
int V;
struct AdjList* array;
};
struct AdjListNode* newAdjListNode(
int dest, int weight)
{
struct AdjListNode* newNode =
(struct AdjListNode*)
malloc(sizeof(struct AdjListNode));
newNode->dest = dest;
newNode->weight = weight;
newNode->next = NULL;
return newNode;
}
struct Graph* createGraph(int V)
{
struct Graph* graph = (struct Graph*)
malloc(sizeof(struct Graph));
graph->V = V;
graph->array = (struct AdjList*)
malloc(V * sizeof(struct AdjList));
for (int i = 0; i < V; ++i)
graph->array[i].head = NULL;
return graph;
}
void lisääTie(struct Graph* graph, int src,
int dest, int weight)
{
struct AdjListNode* newNode =
newAdjListNode(dest, weight);
newNode->next = graph->array[src].head;
graph->array[src].head = newNode;
newNode = newAdjListNode(src, weight);
newNode->next = graph->array[dest].head;
graph->array[dest].head = newNode;
}
struct MinHeapNode
{
int v;
int dist;
};
struct MinHeap
{
int size;
int capacity;
int* pos;
struct MinHeapNode** array;
};
struct MinHeapNode* newMinHeapNode(int v,
int dist)
{
struct MinHeapNode* minHeapNode =
(struct MinHeapNode*)
malloc(sizeof(struct MinHeapNode));
minHeapNode->v = v;
minHeapNode->dist = dist;
return minHeapNode;
}
struct MinHeap* createMinHeap(int capacity)
{
struct MinHeap* minHeap =
(struct MinHeap*)
malloc(sizeof(struct MinHeap));
minHeap->pos = (int*)malloc(
capacity * sizeof(int));
minHeap->size = 0;
minHeap->capacity = capacity;
minHeap->array =
(struct MinHeapNode**)
malloc(capacity *
sizeof(struct MinHeapNode*));
return minHeap;
}
void swapMinHeapNode(struct MinHeapNode** a,
struct MinHeapNode** b)
{
struct MinHeapNode* t = *a;
*a = *b;
*b = t;
}
void minHeapify(struct MinHeap* minHeap,
int idx)
{
int smallest, left, right;
smallest = idx;
left = 2 * idx + 1;
right = 2 * idx + 2;
if (left < minHeap->size &&
minHeap->array[left]->dist <
minHeap->array[smallest]->dist)
smallest = left;
if (right < minHeap->size &&
minHeap->array[right]->dist <
minHeap->array[smallest]->dist)
smallest = right;
if (smallest != idx)
{
MinHeapNode* smallestNode =
minHeap->array[smallest];
MinHeapNode* idxNode =
minHeap->array[idx];
minHeap->pos[smallestNode->v] = idx;
minHeap->pos[idxNode->v] = smallest;
swapMinHeapNode(&minHeap->array[smallest],
&minHeap->array[idx]);
minHeapify(minHeap, smallest);
}
}
int isEmpty(struct MinHeap* minHeap)
{
return minHeap->size == 0;
}
struct MinHeapNode* extractMin(struct MinHeap*
minHeap)
{
if (isEmpty(minHeap))
return NULL;
struct MinHeapNode* root =
minHeap->array[0];
struct MinHeapNode* lastNode =
minHeap->array[minHeap->size - 1];
minHeap->array[0] = lastNode;
minHeap->pos[root->v] = minHeap->size - 1;
minHeap->pos[lastNode->v] = 0;
--minHeap->size;
minHeapify(minHeap, 0);
return root;
}
void decreaseKey(struct MinHeap* minHeap,
int v, int dist)
{
int i = minHeap->pos[v];
minHeap->array[i]->dist = dist;
while (i && minHeap->array[i]->dist <
minHeap->array[(i - 1) / 2]->dist)
{
minHeap->pos[minHeap->array[i]->v] =
(i - 1) / 2;
minHeap->pos[minHeap->array[
(i - 1) / 2]->v] = i;
swapMinHeapNode(&minHeap->array[i],
&minHeap->array[(i - 1) / 2]);
i = (i - 1) / 2;
}
}
bool isInMinHeap(struct MinHeap* minHeap, int v)
{
if (minHeap->pos[v] < minHeap->size)
return true;
return false;
}
void printArr(int dist[], int n)
{
printf("Vertex Distance from Source\n");
for (int i = 0; i < n; ++i)
printf("%d \t\t %d\n", i, dist[i]);
}
void Laske(struct Graph* graph, int src, int pylväs)
{
int V = graph->V;
int dist[200000];
struct MinHeap* minHeap = createMinHeap(V);
for (int v = 0; v < V; ++v)
{
dist[v] = INT_MAX;
minHeap->array[v] = newMinHeapNode(v,
dist[v]);
minHeap->pos[v] = v;
}
minHeap->array[src] =
newMinHeapNode(src, dist[src]);
minHeap->pos[src] = src;
dist[src] = 0;
decreaseKey(minHeap, src, dist[src]);
minHeap->size = V;
while (!isEmpty(minHeap))
{
struct MinHeapNode* minHeapNode =
extractMin(minHeap);
int u = minHeapNode->v;
struct AdjListNode* pCrawl =
graph->array[u].head;
while (pCrawl != NULL)
{
int v = pCrawl->dest;
if (isInMinHeap(minHeap, v) &&
dist[u] != INT_MAX &&
pCrawl->weight + dist[u] < dist[v])
{
dist[v] = dist[u] + pCrawl->weight;
vaihtoehdot[v][pylväs] = dist[v];
decreaseKey(minHeap, v, dist[v]);
}
pCrawl = pCrawl->next;
}
}
}
int main()
{
int V;
cin >> V;
string inputString;
cin.ignore();
getline(cin, inputString);
stringstream stream(inputString);
std::vector<int> valisatamat;
int n;
while (stream >> n) {
valisatamat.push_back(n);
}
for (long unsigned int z = 0; z < valisatamat.size(); z++) {
if (valisatamat[z] == 0) {
satamat.push_back(z);
}
}
int rivimaara = V;
struct Graph* graph = createGraph(V);
for (int i = 0; i < rivimaara - 1; i++) {
string line;
getline(cin, line);
vector<int> rivi = split(line, ' ');
istringstream iss(line);
int num;
iss >> num;
rivi.push_back(num);
lisääTie(graph, rivi[0] - 1, rivi[1] - 1, rivi[2]);
}
for (long unsigned int g = 0; g < satamat.size(); g++) {
Laske(graph, satamat[g], g);
}
int laskin = 0;
for (int j = 0; j < V; j++) {
int pienin = 9999;
for (long unsigned int i = 0; i < satamat.size(); i++) {
if (vaihtoehdot[j][i] < pienin) {
pienin = vaihtoehdot[j][i];
}
}
laskin += pienin;
}
cout << laskin;
return 0;
}