# 題目: UVa 10806 - Dijkstra, Dijkstra

# 題目說明

給一個無向圖,有N個點及M條邊,每條邊的capacity1、有不同的cost
求從起點S走到終點T兩次,求總和最小的cost


INPUT:
每筆測資先輸入兩個整數NM
接下來有M行,每行輸入三個整數uvc,代表edge(u, v)costc;


OUTPUT:
輸出最小的cost,若無法從起點走到終點兩次則輸出Back to jail

# 解題方法

此題的解題概念為Minimum cost Maximum flow
Maximum flow的部分使用Ford Fulkerson演算法
Minimum cost則使用佇列最佳化的bellman ford演算法,又稱Shortest Path Faster Algorithm,簡稱SPFA

基本上與Maximum flow的程式碼相同,只是搜尋起點S是否可以走到終點T時不再是隨便走,而是用SPFA找到minimum cost的路徑
由於每條路只能走一次,所以將capacity設為1
使用一個變數cnt紀錄從起點S走到終點T的次數

# 參考程式碼

#include <iostream>
#include <vector>
#include <queue>
#include <climits>
#define vvint vector< vector<int> >
#define vint vector<int>

using namespace std;

static auto fast_io = []
{
	ios::sync_with_stdio(false);
	cout.tie(nullptr);
	cin.tie(nullptr);
	return 0;
}();

int N, M;
int _s = 1, _t;
vvint edge;
vvint cost;
vvint capacity;
vvint net;
vint dis;
vint p;

void init()
{
	_t = N;
	edge.assign(110, vint());
	cost.assign(110, vint(110, 0));
	capacity.assign(110, vint(110, 0));
	net.assign(110, vint(110, 0));
	p.assign(110, 0);
}

void read()
{
	int u, v, c;

	cin >> M;
	for (int i = 0; i < M; ++i)
	{
		cin >> u >> v >> c;

		edge[u].emplace_back(v);
		edge[v].emplace_back(u);
		cost[u][v] = cost[v][u] = c;
		capacity[u][v] = capacity[v][u] = 1;
	}
}

bool bellman()
{
	dis.assign(110, INT_MAX);
	dis[_s] = 0;

	queue<int> Q;
	vint inQ(110, false);
	Q.emplace(_s);
	inQ[_s] = true;

	while (!Q.empty())
	{
		int u = Q.front();
		Q.pop();
		inQ[u] = false;

		for (auto& v : edge[u])
		{
			if (net[v][u] > 0 && dis[u] + (-cost[v][u]) < dis[v])
				dis[v] = dis[u] + (-cost[v][u]);
			else if (capacity[u][v] > net[u][v] && dis[u] + cost[u][v] < dis[v])
				dis[v] = dis[u] + cost[u][v];
			else continue;

			p[v] = u;
			if (!inQ[v]) Q.emplace(v), inQ[v] = true;
		}
	}

	if (dis[_t] == INT_MAX) return false;
	else return true;
}

void updateflow(int u, int v, int c)
{
	if (v == _s) return;
	net[u][v] += c;
	net[v][u] -= c;
	updateflow(p[u], u, c);
}

void maxflow()
{
	int ret = 0, cnt = 0;

	while (bellman() && ++cnt <= 2)
	{
		ret += dis[_t];
		updateflow(p[_t], _t, 1);
	}

	if (cnt < 2) cout << "Back to jail\n";
	else cout << ret << "\n";
}

int main()
{
	while (cin >> N, N)
	{
		init();
		read();
		maxflow();
	}
}