# Ticket to Ride

### Problem Statement :

```Simon received the board game Ticket to Ride as a birthday present. After playing it with his friends, he decides to come up with a strategy for the game.

There are n cities on the map and n - 1 road plans. Each road plan consists of the following:

Two cities which can be directly connected by a road.
The length of the proposed road.
The entire road plan is designed in such a way that if one builds all the roads, it will be possible to travel between any pair of cities.

A ticket enables you to travel between two different cities. There are m tickets, and each ticket has a cost associated with it. A ticket is considered to be useful if there is a path between those cities.

Simon wants to choose two cities, u and v, and build a minimal number of roads so that they form a simple path between them. Let St  be the sum of costs of all useful tickets and Sr  be the sum of lengths of all the roads Simon builds. The profit for pair ( u, v )  is defined as St - Sr. Note that u and v are not necessarily unique and may be the same cities.

Given n road plans and m ticket prices, help Simon by printing the value of his maximum possible profit on a new line.

Input Format

The first line contains single positive integer, n , denoting the number of cities.
Each of the n - 1  subsequent lines contains three space-separated integers describing the respective values of u , v, and  l for a road plan, where , 1 <= u ,v <= l and u =/ v . Here, u and v are two cities that the road plan proposes to connect and l  is the length of the proposed road.
The next line contains a single positive integer, m, denoting the number of tickets.
Each of the m subsequent lines contains three space-separated integers describing the respective values of u, v, and c for a ticket from city u  to city v (where c is the cost of the ticket).

Constraints

1  <=  n  <=  2 x 10^5
1  <=  m  <=  10^5
1  <=  l , c  <=  10^9

Output Format

Print a single integer denoting the the maximum profit Simon can make.```

### Solution :

```                            ```Solution in C :

In   C++  :

#include <bits/stdc++.h>

using namespace std;

#define sz(x) ((int) (x).size())
#define forn(i,n) for (int i = 0; i < int(n); ++i)
#define forab(i,a,b)for(int i =int(a);i<int(b);++i)

typedef long long ll;
typedef long double ld;

const int INF = 1000001000;
const ll INFL = 2000000000000001000;
int solve();

int main()
{
srand(2317);
cout.precision(10);
cout.setf(ios::fixed);
#ifdef LOCAL
assert(freopen("test.in", "r", stdin));
#else
#endif
int tn = 1;
for (int i = 0; i < tn; ++i)
solve();
#ifdef LOCAL
cerr << "Time: " << double(clock()) /
CLOCKS_PER_SEC << '\n';
#endif
}

const int maxn = 500001;
const int maxm = 100001;
const int maxh = 19;

int ROOT;

int n;
vector<pair<int, int>> g[maxn];
int in[maxn], out[maxn];
int timer = 0;

const int base = 1 << maxh;
ll t[base * 2];
ll upd[base * 2];

ll get()
{
return t[1] + upd[1];
}

int l, r, delta;
inline void put(int v = 1,
int cl = 0, int cr = base)
{
if (r <= cl || cr <= l)
return;
if (l <= cl && cr <= r)
{
upd[v] += delta;
return;
}
int cc = (cl + cr) >> 1;
put(v << 1, cl, cc);
put((v << 1) + 1, cc, cr);
t[v] = max(t[v << 1] + upd[v << 1],
t[(v << 1) + 1] + upd[(v << 1) + 1]);
}

inline void add(int v, ll delta)
{
l = in[v], r = out[v], ::delta = delta;
put();
}

vector<pair<int, int>> up[maxn];
vector<pair<int, int>> down[maxn];
vector<pair<int, int>> other[maxn];

inline bool is_prev(int u, int v)
{
return in[u] <= in[v] && out[v] <= out[u];
}

ll best = 0;

void go(int u, int prev = ROOT)
{
for (auto p: other[u])
for (auto p: down[u])
{
upd[1] += p.second;
}
for (auto p: up[u])
best = max(best, get());
for (auto p: g[u])
{
if (p.first == prev)
continue;
upd[1] -= p.second;
go(p.first, u);
upd[1] += p.second;
}
for (auto p: other[u])
for (auto p: down[u])
{
upd[1] -= p.second;
}
for (auto p: up[u])
}

pair<int, int> tickets[maxm];
int ticket_cost[maxm];
int visits[maxm];
int needh[maxm];
int step[maxm];
vector<int> endings[maxn];

int st[maxn], sc = 0;

void dfs(int u, int prev = ROOT, ll depth = 0)
{
st[sc++] = u;
for (int id: endings[u])
{
visits[id]++;
if (visits[id] == 1)
needh[id] = sc;
else if (visits[id] == 2)
step[id] = st[needh[id]];
}
in[u] = timer++;
t[in[u] + base] = -depth;

for (auto p: g[u])
if (p.first != prev)
dfs(p.first, u, depth + p.second);

for (int id: endings[u])
visits[id]--;
out[u] = timer;
--sc;
}

int solve()
{
scanf("%d", &n);
ROOT = rand() % n;
forn (i, n - 1)
{
int u, v, l;
scanf("%d %d %d", &u, &v, &l);
--u, --v;
g[u].emplace_back(v, l);
g[v].emplace_back(u, l);
}
int m;
scanf("%d", &m);
forn (i, m)
{
int u, v, c;
scanf("%d %d %d", &u, &v, &c);
--u, --v;
endings[u].push_back(i);
endings[v].push_back(i);
tickets[i] = {u, v};
ticket_cost[i] = c;
}
fill(step, step + m, -1);
dfs(ROOT);
for (int i = base - 1; i > 0; --i)
t[i] = max(t[i * 2], t[i * 2 + 1]);
forn (i, m)
{
int u = tickets[i].first;
int v = tickets[i].second;
int c = ticket_cost[i];
if (is_prev(v, u))
swap(u, v);
if (is_prev(u, v))
{
assert(step[i] >= 0);
assert(is_prev(u, step[i]));
assert(is_prev(step[i], v));
u = step[i];
up[u].emplace_back(v, c);
down[v].emplace_back(u, c);
}
else
{
other[u].emplace_back(v, c);
other[v].emplace_back(u, c);
}
}
go(ROOT);
cout << best << '\n';
return 0;
}

In   Python3  :

#!/bin/python3

import os
import sys
from queue import Queue
class Graph:
self.n = n
self.tree = dict()
for i in range(n):
self.tree[i+1] = []

def find_path(self, a, b, visited):
if visited is None:
visited = set()
if a==b:
return set([a]), 0
for c, d in self.tree[a]:
if c not in visited:
path, p_length = self.find_path(c, b, visited)
if path is not None:
ext_path = path.copy()
return ext_path, p_length + d
return None, 0

# Complete the solve function below.
max_score = 0
for a, b, _ in tickets:
path, cost = g.find_path(a, b, None)
score = - cost
for t in tickets:
if set(t[:2]).issubset(path):
score += t[2]
if score > max_score:
max_score = score
return max_score

if __name__ == '__main__':
fptr = open(os.environ['OUTPUT_PATH'], 'w')

n = int(input())

for _ in range(n-1):

m = int(input())

tickets = []

for _ in range(m):
tickets.append(list(map(int, input().rstrip().split())))

fptr.write(str(result) + '\n')

fptr.close()```
```

## Insert a node at a specific position in a linked list

Given the pointer to the head node of a linked list and an integer to insert at a certain position, create a new node with the given integer as its data attribute, insert this node at the desired position and return the head node. A position of 0 indicates head, a position of 1 indicates one node away from the head and so on. The head pointer given may be null meaning that the initial list is e

## Delete a Node

Delete the node at a given position in a linked list and return a reference to the head node. The head is at position 0. The list may be empty after you delete the node. In that case, return a null value. Example: list=0->1->2->3 position=2 After removing the node at position 2, list'= 0->1->-3. Function Description: Complete the deleteNode function in the editor below. deleteNo

## Print in Reverse

Given a pointer to the head of a singly-linked list, print each data value from the reversed list. If the given list is empty, do not print anything. Example head* refers to the linked list with data values 1->2->3->Null Print the following: 3 2 1 Function Description: Complete the reversePrint function in the editor below. reversePrint has the following parameters: Sing