Longest Mod Path


Problem Statement :


n the middle of a nightmare, Maxine suddenly finds herself in a mysterious room with the following items:

A piece of paper with the word score and the integer  written on it.
A map of the castle where the room is located.
There are  rooms uniquely labeled from  to .
There are  bidirectional corridors connecting pairs of rooms. The value of score changes every time she travels up or down a corridor, and this value differs depending on her direction of travel along the corridor. Each corridor can be traveled any number of times in either direction.
Every room is reachable from every other room.
Maxine is located in the room labeled .
The exit is located in the room labeled . Once this room is reached, score is reduced modulo  and Maxine can (but is not required to) exit that level!
Assume some corridor  (where ) is associated with an integer, , and connects rooms  and . Then:

Traveling corridor  from room  to room  increases score by .
Traveling corridor  from room  to room  decreases score by .
There are  levels to Maxine's nightmare castle, and each one has a different set of values for , , and . Given the above information, help Maxine by finding and printing her maximum possible score for each level. Only you can help her wake up from this nightmare!

Note: Recall that the result of a modulo operation is always non-negative. For example, .

Input Format

The first line contains a single integer, , denoting the number of rooms.
Each of the  subsequent lines describes a corridor in the form of three space-separated integers denoting the respective values for , , and .
The next line contains a single integer, , denoting the number of queries.
Each of the  subsequent lines describes a level in the form of three space-separated integers denoting its respective , , and  values.

Constraints

, 
For each level:

The room layout is the same



Solution :



title-img


                            Solution in C :

In C++ :





#include <cstdio>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <ctime>
#include <cstring>
#include <cassert>
#include <bitset>
#include <sstream>
#include <queue>

#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define sz(a) ((int) (a).size())
#define eprintf(...) fprintf(stderr, __VA_ARGS__)

using namespace std;

typedef long long int64;
typedef long double ldb;

const long double eps = 1e-9;
const int inf = (1 << 30) - 1;
const long long inf64 = ((long long)1 << 62) - 1;
const long double pi = acos(-1);

template <class T> T sqr (T x) {return x * x;}
template <class T> T abs (T x) {return x < 0 ? -x : x;}

const int MAXN = 120 * 1000;

vector <pair <int, int> > adj[MAXN];
long long a[MAXN];
bool used[MAXN];
long long cycle = 0;

void dfs(int v, long long num) {
    a[v] = num;
    used[v] = true;
    for (int i = 0; i < sz(adj[v]); ++i) {
        int u = adj[v][i].fs;
        if (!used[u]) {
            dfs(u, num + adj[v][i].sc);
        } else if (a[v] + adj[v][i].sc - a[u] != 0) {
            cycle = a[v] + adj[v][i].sc - a[u];
        }
    }
}

int gcd(int a, int b) {
    return (a == 0 ? b : gcd(b % a, a));
}

int main () {
//  ios_base::sync_with_stdio(0);
 // freopen("input.txt", "rt", stdin);
//  freopen("output.txt", "wt", stdout);

    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        int v1, v2, c;
        scanf("%d%d%d", &v1, &v2, &c);
        v1--, v2--;
        adj[v1].pb(mp(v2, c));
        adj[v2].pb(mp(v1, -c));
    }

    dfs(0, 0);
    
    int q;
    scanf("%d", &q);
    for (int i = 0; i < q; ++i) {
        int s, e, m;
        scanf("%d%d%d", &s, &e, &m);
        s--, e--;
        
        int val = ((a[e] - a[s]) % m + m) % m;
        int cycle_val = (cycle % m  + m) % m;
        
       // cerr << val << " " << cycle_val << " " << m << endl;
        
        int d = gcd(cycle_val, m);

       // cerr << d << endl;

        int res = (val % d) + m - d;
        printf("%d\n", res);
    }

    return 0;
}








In C :






#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HASH_SIZE 123455
#define INF 1000000007
typedef struct _node{
  int x;
  int y;
  int w;
  struct _node *next;
} node;
typedef struct _lnode{
  int x;
  int w;
  struct _lnode *next;
} lnode;
void insert_edge(int x,int y,int w);
void dfs0(int x,int y);
void dfs1(int x);
void get_loop(int x,int y);
long long CC(long long n, long long d);
void insert(int x,int y,int w);
int search(int x,int y);
lnode *table[100000]={0};
node *hash[HASH_SIZE]={0};
int loop[100000]={0},trace[100000]={0},point[100000];
int first_point,breakp=0,cycle_found=0;
long long cycle=0,dis[100000]={0},cycle_save;

int main(){
  int N,a,b,x,S,E,M,Q,MOD,DIS,GCD,ans,i;
  scanf("%d",&N);
  for(i=0;i<N;i++){
    scanf("%d%d%d",&a,&b,&x);
    insert_edge(a-1,b-1,x);
    if(a>b)
      Q=search(b-1,a-1);
    else
      Q=search(a-1,b-1);
    if(Q==INF)
      if(a>b)
        insert(b-1,a-1,-x);
      else
        insert(a-1,b-1,x);
    else{
      if(a>b)
        cycle=x+Q;
      else
        cycle=x-Q;
      cycle_found=1;
      cycle_save=cycle;
    }
  }
  dfs0(0,-1);
  if(!loop[0])
    point[0]=first_point;
  memset(trace,0,sizeof(trace));
  dfs1(0);
  if(cycle_found)
    cycle=cycle_save;
  scanf("%d",&Q);
  while(Q--){
    scanf("%d%d%d",&S,&E,&M);
    MOD=(cycle%M+M)%M;
    DIS=((dis[E-1]-dis[S-1])%M+M)%M;
    if(!MOD)
      ans=DIS;
    else{
      GCD=CC(MOD,M);
      ans=(M-1-DIS)/GCD*GCD+DIS;
    }
    printf("%d\n",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 dfs0(int x,int y){
  lnode *p;
  trace[x]=1;
  for(p=table[x];p;p=p->next)
    if(!trace[p->x]){
      dis[p->x]=dis[x]+p->w;
      dfs0(p->x,x);
    }
    else if(p->x!=y && !loop[p->x]){
      first_point=p->x;
      get_loop(p->x,-1);
      cycle+=p->w;
    }
  return;
}
void dfs1(int x){
  lnode *p;
  trace[x]=1;
  if(loop[x])
    point[x]=x;
  for(p=table[x];p;p=p->next)
    if(!trace[p->x]){
      if(!loop[p->x])
        point[p->x]=point[x];
      dfs1(p->x);
    }
  return;
}
void get_loop(int x,int y){
  lnode *p;
  loop[x]=1;
  for(p=table[x];p && !breakp;p=p->next)
    if(trace[p->x] && !loop[p->x]){
      cycle+=p->w;
      get_loop(p->x,x);
      if(!breakp)
        cycle-=p->w;
    }
    else if(p->x==first_point && p->x!=y){
      breakp=1;
      break;
    }
  return;
}
long long CC(long long n, long long d){
    while( 1 )
    {
        n = n % d;
        if( n == 0 )
                return d;
        d = d % n;
        if( d == 0 )
                return n;
    }
}
void insert(int x,int y,int w){
  int bucket=(x*100000LL+y)%HASH_SIZE;
  node *t;
  t=(node*)malloc(sizeof(node));
  t->x=x;
  t->y=y;
  t->w=w;
  t->next=hash[bucket];
  hash[bucket]=t;
  return;
}
int search(int x,int y){
  int bucket=(x*100000LL+y)%HASH_SIZE;
  node *t=hash[bucket];
  while(t){
    if(t->x==x && t->y==y)
      return t->w;
    t=t->next;
  }
  return INF;
}








In Python3 :






from fractions import gcd

n=int(input())
adjlst = [[] for i in range(n)]
for j in range(0,n):
    arr=list(map(int,input().split()))
    a=arr[0]-1
    b=arr[1]-1
    c=arr[2]
    adjlst[a].append((b,c))
    adjlst[b].append((a,-c))



dist = [None]*n
parents = [set() for i in range(n)] 
dist[0] = 0
stack = [0]
while stack:
    i = stack.pop()
    for j, c in adjlst[i]:
        if j in parents[i]: continue
        dist1 = dist[i] + c
        parents[j].add(i)
        if dist[j] is None:
            dist[j] = dist1
            stack.append(j)
        else:
            cycle = abs(dist[j] - dist1)
q=int(input())
for j in range(0,q):

    arr1=list(map(int,input().split()))
    s=arr1[0]
    e=arr1[1]
    m=arr1[2]
    a = gcd(cycle, m)
    print (m - a + (dist[e-1] - dist[s-1]) % a)
                        








View More Similar Problems

Queue using Two Stacks

A queue is an abstract data type that maintains the order in which elements were added to it, allowing the oldest elements to be removed from the front and new elements to be added to the rear. This is called a First-In-First-Out (FIFO) data structure because the first element added to the queue (i.e., the one that has been waiting the longest) is always the first one to be removed. A basic que

View Solution →

Castle on the Grid

You are given a square grid with some cells open (.) and some blocked (X). Your playing piece can move along any row or column until it reaches the edge of the grid or a blocked cell. Given a grid, a start and a goal, determine the minmum number of moves to get to the goal. Function Description Complete the minimumMoves function in the editor. minimumMoves has the following parameter(s):

View Solution →

Down to Zero II

You are given Q queries. Each query consists of a single number N. You can perform any of the 2 operations N on in each move: 1: If we take 2 integers a and b where , N = a * b , then we can change N = max( a, b ) 2: Decrease the value of N by 1. Determine the minimum number of moves required to reduce the value of N to 0. Input Format The first line contains the integer Q.

View Solution →

Truck Tour

Suppose there is a circle. There are N petrol pumps on that circle. Petrol pumps are numbered 0 to (N-1) (both inclusive). You have two pieces of information corresponding to each of the petrol pump: (1) the amount of petrol that particular petrol pump will give, and (2) the distance from that petrol pump to the next petrol pump. Initially, you have a tank of infinite capacity carrying no petr

View Solution →

Queries with Fixed Length

Consider an -integer sequence, . We perform a query on by using an integer, , to calculate the result of the following expression: In other words, if we let , then you need to calculate . Given and queries, return a list of answers to each query. Example The first query uses all of the subarrays of length : . The maxima of the subarrays are . The minimum of these is . The secon

View Solution →

QHEAP1

This question is designed to help you get a better understanding of basic heap operations. You will be given queries of types: " 1 v " - Add an element to the heap. " 2 v " - Delete the element from the heap. "3" - Print the minimum of all the elements in the heap. NOTE: It is guaranteed that the element to be deleted will be there in the heap. Also, at any instant, only distinct element

View Solution →