Language: C++

#include <iostream>
#include <vector>
#include <queue>
#include <unordered_set>
#include <string>
#include <algorithm>
#include <utility>
#include <cstring>

using namespace std;

template <typename T>
using reverse_queue = std::priority_queue<T, std::vector<T>, std::greater<T> >;
#define REP(var, count) for(int var=0; var<count; var++)

const int INF = 1000001000;

struct rosen {
	int start;
	int dest;
	int km;
	int comp;
};

int calc(vector<pair<int, int> > &table, int km) {
	int ret = 0;
	int prev = 0;
	for( auto x : table ) {
		if ( km > x.first ) {
			ret += x.second * (x.first - prev);
			prev = x.first;
		} else {
			return ret + x.second * (km - prev);
		}
	}
	throw;
}

bool loop(void) {
	int N, M, C, s, g;
	cin >> N >> M >> C >> s >> g;
	if ( N == 0 ) { return false; }
	
	s--;
	g--;
	
	vector<rosen> line;
	
	REP(i, M) {
		int x, y, d, c;
		cin >> x >> y >> d >> c;
		
		x--;
		y--;
		c--;
		
		line.push_back( rosen{x,y,d,c} );
		line.push_back( rosen{y,x,d,c} );
	}
	
	vector<pair<int, int> > table[22];
	
	int ppp[22];
	REP(i, C) {
		cin >> ppp[i];
	}
	
	REP(i, C) {
		table[i].push_back( make_pair(0,0) );
		REP(x, ppp[i] - 1) {
			int ky;
			cin >> ky;
			table[i].push_back( make_pair(ky, -1) );
		}
		table[i].push_back( make_pair(INT_MAX, -1) );
		REP(x, ppp[i]) {
			int co;
			cin >> co;
			table[i][x+1].second = co;
		}
	}
	
	struct node {
		int first; //??????
		int second; //??£?¶??????¢
		unordered_set<int> trace;
	};
	
	node memo[102][22][2]; //[?§?][??????][?????????????????£?¶??????¢??????]
	REP(e, N) {
		REP(c, C) {
			if ( e == s ) {
				memo[e][c][0] = node{0,0,{s}};
				memo[e][c][1] = node{0,0,{s}};
			} else {
				memo[e][c][0] = node{INF,0,{}};
				memo[e][c][1] = node{INF,0,{}};
			}
		}
	}
	
	REP(rr, N*C*2) {
		bool update = false;
			
		for ( auto l : line ) {
			REP(c, C) {
				REP(b, 2) {
					if ( memo[l.start][c][b].first == INF ) { continue; }
					
					if ( memo[l.start][c][b].trace.count(l.dest) != 0 ) { continue; }
					
					int nextcost = memo[l.start][c][b].first;
					int nextkm;
					if ( c == l.comp ) {
						nextkm = memo[l.start][c][b].second + l.km;
						nextcost += -calc(table[l.comp], memo[l.start][c][b].second) + calc(table[l.comp], nextkm);
					} else {
						nextkm = l.km;
						nextcost += calc(table[l.comp], l.km);
					}
					
					if ( nextcost < memo[l.dest][l.comp][0].first ) {
						memo[l.dest][l.comp][0] = node{nextcost, nextkm, memo[l.start][c][b].trace};
						memo[l.dest][l.comp][0].trace.insert(l.dest);
						//printf("memo[%d][%d][%d] = make_pair(%d, %d)\n", l.dest, l.comp, 0, nextcost, nextkm);
						update = true;
						break;
					} else if ( nextkm > memo[l.dest][l.comp][1].second ) {
						memo[l.dest][l.comp][1] = node{nextcost, nextkm, memo[l.start][c][b].trace};
						memo[l.dest][l.comp][1].trace.insert(l.dest);
						//printf("memo[%d][%d][%d] = make_pair(%d, %d)\n", l.dest, l.comp, 1, nextcost, nextkm);
						update = true;
						break;
					}
				}
				
				if ( update ) { break; }
			}
			
			if ( update ) { break; }
		}
		
		if ( !update ) { break; }
	}
	
	int ret = INF;
	REP(c, C) {
		REP(b, 2) {
			ret = min(ret, memo[g][c][b].first);
		}
	}
	if ( ret == INF ) {
		cout << -1 << endl;
	} else {
		cout << ret << endl;
	}
	
	return true;

}

int main(void) {
	while ( loop() ) {}
}

Compiler output:
a.cc: In function 'bool loop()':
a.cc:75:47: error: 'INT_MAX' was not declared in this scope
   75 |                 table[i].push_back( make_pair(INT_MAX, -1) );
      |                                               ^~~~~~~
a.cc:9:1: note: 'INT_MAX' is defined in header '<climits>'; this is probably fixable by adding '#include <climits>'
    8 | #include <cstring>
  +++ |+#include <climits>
    9 |