和SGU 185 Two shortest有点类似。。就是求从源点到终点的再从终点到源点的最短路,但是不能经过同一条边两次。
费用流,原来边的长度作为花费,容量为1,再建新源点到旧源点容量为2,新汇点和旧汇点容量为2,求最小费用就为最短路径。如果不存在则新源点到旧源点的容量小于2。
这题貌似也有多种解法。费用流不唯一。
#include <iostream>
using namespace std;
#define N 105
#define INF 1 << 29
struct node
{
int cap, cost;
}g[N][N];
int pre[N], d[N], map[N][N];
bool spfa(int src, int sink)
{
int que[N * N], front, top, u;
bool in[N];
for(int i = 0; i <= sink; i++)
{
d[i] = INF;
in[i] = 0;
}
in[src] = 1;
d[src] = front = top = 0;
pre[src] = src;
que[top++] = src;
while(front < top)
{
u = que[front++];
in[u] = 0;
for(int i = 0; i <= sink; i++)
{
if(g[u][i].cap > 0 && d[u] + g[u][i].cost < d[i])
{
d[i] = d[u] + g[u][i].cost;
pre[i] = u;
if(!in[i])
{
que[top++] = i;
in[i] = 1;
}
}
}
}
return d[sink] != INF;
}
int mincost(int src, int sink)
{
int ans = 0, flow;
while(spfa(src, sink))
{
flow = INF;
for(int i = sink; i != src; i = pre[i])
{
if(flow > g[pre[i]][i].cap)
flow = g[pre[i]][i].cap;
}
for(int i = sink; i != src; i = pre[i])
{
g[pre[i]][i].cap -= flow;
g[i][pre[i]].cap += flow;
g[i][pre[i]].cost = -g[pre[i]][i].cost;
}
ans += d[sink] * flow;
}
return ans;
}
int main()
{
int n, m, ans;
while(scanf("%d", &n), n)
{
scanf("%d", &m);
memset(g, 0, sizeof(g));
for(int i = 0; i < m; i++)
{
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
g[a][b].cap = g[b][a].cap = 1;
g[a][b].cost = g[b][a].cost = c;
}
g[0][1].cap = g[1][0].cap = 2;
g[n][n + 1].cap = g[n + 1][n].cap = 2;
ans = mincost(0, n + 1);
if(g[0][1].cap) puts("Back to jail");
else printf("%d\n", ans);
}
return 0;
}