#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <queue>
using namespace std;
typedef long long ll;
#define st first
#define nd second
#define f(a, c, b) for (int a = c; b > a; a++)
#define pb push_back
#define all(a) a.begin(), a.end()
#define sz(a) int(a.size())
vector<vector<int>> g; //bedzie zawierac ind krawedzi
vector<unordered_map<int, int>> ile; //ile wchodzi danego rodzaju do wierzcholka
vector<unordered_map<int, ll>> suma;
vector<pair<pair<int, int>, pair<int, ll>>> e; //krawedzie
pair<int, pair<int, ll>> kr(int v, int ind) {
	if (e[ind].st.st == v) return {e[ind].st.nd, {e[ind].nd.st, e[ind].nd.nd}};
	return {e[ind].st.st, e[ind].nd};
}
ll wnk = 213769420696969;
int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	int n, m;
	cin >> n >> m;
	g.resize(n + 1);
	e.resize(m + 1);
	ile.resize(n + 1);
	suma.resize(n + 1);
	f(i, 1, m + 1) {
		int a, b, c;
		ll p;
		cin >> a >> b >> c >> p;
		ile[a][c]++;
		ile[b][c]++;
		suma[a][c] += p;
		suma[b][c] += p;
		g[a].pb(i);
		g[b].pb(i);
		e[i] = {{a, b}, {c, p}};
	}
	const ll DUZO = 1000000;
	priority_queue<pair<ll, ll>> kolejka; //koszt - zahaszowany wierzcholek
	kolejka.push({0, 1});
	unordered_map<ll, ll> ans; //odpowiedzi
	while (!kolejka.empty()) {
		ll koszt = -kolejka.top().st;
		if (ans.find(kolejka.top().nd) != ans.end()) {kolejka.pop(); continue;}
		ans[kolejka.top().nd] = koszt;
		int v = kolejka.top().nd%(DUZO);
		int ind = kolejka.top().nd/DUZO;
		//cout << "int v to " << v << " ind to " << ind << "  koszt to " << koszt << "\n";
		kolejka.pop();
		if (v == n) {
			cout << koszt;
			return 0;
		}
		int kolor = -1;
		if (ind != 0) {
			kolor = kr(v, ind).nd.st;
			ile[v][kolor]--;
			suma[v][kolor] -= kr(v, ind).nd.nd;
		}
		//cout << "a";
		for (int ele: g[v]) {
			//cout << ele << " ";
			pair<int, pair<int, ll>> u = kr(v, ele);
			if (ile[v][u.nd.st] == 1) {
				if (ans.find(u.st) == ans.end()) {
					kolejka.push({-koszt, u.st});
				} 
			} else {
				ll pot = u.st + ll(ele) * DUZO;
				if (ans.find(pot) == ans.end()) {
					kolejka.push({-(koszt + u.nd.nd), pot});
				}
				if (u.nd.nd > (suma[v][u.nd.st] - u.nd.nd)) {
					if (ans.find(u.st) == ans.end()) kolejka.push({-(koszt + (suma[v][u.nd.st] - u.nd.nd)), u.st});
				}
			}
		}
		if (kolor != -1) {ile[v][kolor]++; suma[v][kolor] += kr(v, ind).nd.nd;}
		//cout << "\n";
	}
	if (wnk == 213769420696969) {
		cout << -1;
	} else {
		cout << wnk;
	}
	return 0;
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |