# HackerRank Jeanie's Route problem solution

In this HackerRank Jeanie's Route problem solution Byteland has N cities (numbered from 1 to N) and N - 1 bidirectional road. It is guaranteed that there is a route from any city to any other city.

Jeanie is a postal worker who must deliver K letters to various cities in Byteland. She can start and end her delivery route in any city. Given the destination cities for K letters and the definition of each road in Byteland, find and print the minimum distance Jeanie must travel to deliver all K letters.

## Problem solution in Python.

```def farthest_node_from_start(nodes,is_goal,subtree,starting_node):
visited=[False for _ in nodes]
st=[(0,starting_node)]
visited[starting_node]=True
largest = 0,starting_node
all_dist_sum = 0
while st:
dist,u=st.pop()
for v,d in nodes[u]:
if not visited[v] and subtree[v]:
elm=dist+d,v
all_dist_sum+=d
if is_goal[v]:
largest=max(largest,elm)
st.append(elm)
visited[v]=True
return all_dist_sum,largest

def make_subtree(nodes,is_goal,starting_node):
subtree=is_goal[:]
for u,v in dfs(nodes, starting_node):
subtree[u]=subtree[u] or subtree[v]
return subtree

def dfs(nodes, starting_node):
stack = [(starting_node, v) for v,d in nodes[starting_node]]
edges = list()
while stack:
u, v = stack.pop()
edges.append((u, v))
stack.extend((v, w) for w,d in nodes[v] if w != u)
edges.reverse()
return edges

N, K = list(map(int,input().strip().split()))
goals = list(map(int,input().strip().split()))
is_goal=[False]*(N+1)

for item in goals:
is_goal[item]=True

nodes=[[] for _ in range(N+1)]

for _ in range(N-1):
u,v,d = list(map(int,input().strip().split()))
nodes[u].append((v,d))
nodes[v].append((u,d))

subtree = make_subtree(nodes,is_goal,goals[0])
a,(b,c)=farthest_node_from_start(nodes,is_goal,subtree,goals[0])
Distance,(d,_)=farthest_node_from_start(nodes,is_goal,subtree,c)
print(2*Distance-d)
```

{"mode":"full","isActive":false}

## Problem solution in Java.

```import java.util.Scanner;
import java.util.Queue;
import java.util.ArrayDeque;

class Solution{
static boolean[] prune(int[][][] adj, boolean[] isLett){
int[] degree=new int[n];
boolean[] rem=new boolean[n];
Queue<Integer> q=new ArrayDeque<>();
for(int i=0;i<n;++i){
}
while(!q.isEmpty()){
int leaf=q.remove();
rem[leaf]=true;
int node=edge[0];
if(isLett[node]) break;
else if(!rem[node]){
if(--degree[node] == 1){
break;
}
}
}
}
return rem;
}
static int[] bfs(int[][][] adj, boolean[] rem, int source){
int[] dist=new int[n];
for(int i=0;i<n;++i) dist[i]=unvis;
Queue<Integer> q=new ArrayDeque<>();
dist[source]=0;
int best=0, total=0;
while(!q.isEmpty()){
int x=q.remove();
int to=edge[0];
if(!rem[to] && dist[to]==unvis){
int weight=edge[1];
total+=weight;
dist[to]=dist[x]+weight;
if(dist[to]>dist[best]) best=to;
}
}
}
int[] result={total,dist[best],best};
return result;
}
static int solve(int[][][] adj, int[] lett){
for(int i: lett) isLett[i]=true;
int totalWeight=result[0], sink=result[2];
int diameter=result[1];
return 2*totalWeight-diameter;
}
static int[][][] weightedAdjacency(int n, int[] from, int[] to, int[] d){
int[] count=new int[n];
for(int f: from) ++count[f];
for(int t: to) ++count[t];
for(int i=0;i<from.length;++i){
}
}
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt(), k=sc.nextInt();
int[] lett=new int[k];
for(int i=0;i<k;++i) lett[i]=sc.nextInt()-1;
int[] from=new int[n-1], to=new int[n-1], d=new int[n-1];
for(int i=0;i<n-1;++i){
from[i]=sc.nextInt()-1;
to[i]=sc.nextInt()-1;
d[i]=sc.nextInt();
}
sc.close();
}
}
```

{"mode":"full","isActive":false}

## Problem solution in C++.

```#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define MA(x,y) ((x)>(y)?(x):(y))
using namespace std;
const int N=500002;
const int inf=1000000000;
int n,K,s[N],SUM,M;
bool f[N];
vector <int> v[N],d[N];

int input(){
scanf("%d%d",&n,&K);
for (int i=0,x;i<K;i++){
scanf("%d",&x);
s[x]=1;
f[x]=1;
}
for (int i=1,x,y,z;i<n;i++){
scanf("%d%d%d",&x,&y,&z);
v[x].pb(y);
v[y].pb(x);
d[x].pb(z);
d[y].pb(z);
}
return 0;
}

int go(int x,int from){
int D1=-inf;
int D2=-inf;

for (int i=0;i<v[x].size();i++)
if (v[x][i]!=from){
D1=max(D1,go(v[x][i],x)+d[x][i]);
if (D1>D2) swap(D1,D2);
s[x]+=s[v[x][i]];
if (0<s[v[x][i]] && s[v[x][i]]<K) SUM+=d[x][i];
}

if (D1>0) M=max(M,D1+D2);

if (D2>0 && f[x]) M=max(M,D2);

if (f[x]) D2=max(D2,0);

return D2;
}

int sol(){
go(1,1);
printf("%d\n",SUM*2-M);
return 0;
}

int main() {
input();
sol();
return 0;
}```

{"mode":"full","isActive":false}

## Problem solution in C.

```#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _node{
int x;
int w;
struct _node *next;
} lnode;
void insert_edge(int x,int y,int w);
void dfs1(int x);
void dfs2(int x,int y,int z);
int max(int x,int y);
int mark[100000]={0},count[100000],trace[100000],l[100000],ul[100000],s[100000],sc[100000],len[100000],ulen[100000],ans=2147483647;
lnode *table[100000]={0};

int main(){
int N,K,x,y,w,i;
scanf("%d%d",&N,&K);
while(K--){
scanf("%d",&x);
mark[x-1]=1;
}
for(i=0;i<N-1;i++){
scanf("%d%d%d",&x,&y,&w);
insert_edge(x-1,y-1,w);
}
memset(trace,0,sizeof(trace));
dfs1(0);
memset(trace,0,sizeof(trace));
dfs2(0,-1,-1);
printf("%d",ans);
return 0;
}
void insert_edge(int x,int y,int w){
lnode *t=malloc(sizeof(lnode));
t->x=y;
t->w=w;
t->next=table[x];
table[x]=t;
t=malloc(sizeof(lnode));
t->x=x;
t->w=w;
t->next=table[y];
table[y]=t;
return;
}
void dfs1(int x){
lnode *p;
trace[x]=1;
if(mark[x])
count[x]=1;
else
count[x]=0;
l[x]=s[x]=sc[x]=len[x]=0;
for(p=table[x];p;p=p->next)
if(!trace[p->x]){
dfs1(p->x);
count[x]+=count[p->x];
if(count[p->x]){
sc[x]++;
len[x]+=len[p->x]+2*p->w;
if(l[p->x]+p->w>l[x]){
s[x]=l[x];
l[x]=l[p->x]+p->w;
}
else if(l[p->x]+p->w>s[x])
s[x]=l[p->x]+p->w;
}
}
return;
}
void dfs2(int x,int y,int z){
lnode *p;
int rl,rs;
trace[x]=1;
if(y==-1)
ulen[x]=ul[x]=0;
else{
if(count[0]-count[x]){
ulen[x]=len[y]+ulen[y]-len[x];
if(!count[x])
ulen[x]+=2*z;
if(l[y]==z+l[x])
ul[x]=z+max(s[y],ul[y]);
else
ul[x]=z+max(l[y],ul[y]);
}
else
ulen[x]=ul[x]=0;
}
rl=l[x];
rs=s[x];
if(ul[x]>rl){
rs=rl;
rl=ul[x];
}
else if(ul[x]>rs)
rs=ul[x];
if(len[x]+ulen[x]-rl-rs<ans)
ans=len[x]+ulen[x]-rl-rs;
for(p=table[x];p;p=p->next)
if(!trace[p->x])
dfs2(p->x,x,p->w);
return;
}
int max(int x,int y){
return (x>y)?x:y;
}

```

{"mode":"full","isActive":false}