求一条从s到t的回路,要求每条边只走一次,使总和最小。最小费用最大流。将每条边的流量设为1,答案就是最大流为2时的最小费用。
求最短路的时候用了SPFA。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#define MAXN 105
#define INF 2139062143
#define ll long long
//ios::sync_with_stdio(false);
using namespace std;
int n;
struct Edge
{
int to,from,cap,cost,rev;
Edge(int a,int b,int c,int d,int e):to(a),from(b),cap(c),cost(d),rev(e) {}
};
vector<Edge> gl[MAXN];
int prev[MAXN],pree[MAXN];
void add_edge(int to,int from,int cap,int cost)
{
gl[from].push_back(Edge(to,from,cap,cost,gl[to].size()));
gl[to].push_back(Edge(from,to,0,-cost,gl[from].size()-1));
}
void Init(int n)
{
for(int i=0; i<=n; ++i) gl[i].clear();
memset(prev,0,sizeof(prev));
memset(pree,0,sizeof(pree));
}
int min_cost_flow(int s,int t,int f)
{
int res=0;
while(f>0)
{
int dist[MAXN];
memset(dist,0x7f,sizeof(dist));
dist[s]=0;
bool inque[MAXN];
memset(inque,0,sizeof(inque));
queue<int> que;
que.push(s);
inque[s]=true;
while(!que.empty())
{
int q=que.front();
que.pop();
inque[q]=false;
for(int i=0; i<gl[q].size(); ++i)
{
Edge e=gl[q][i];
int to=e.to;
if(e.cap>0&&dist[to]>dist[q]+e.cost)
{
dist[to]=dist[q]+e.cost;
prev[to]=q;
pree[to]=i;
if(!inque[to])
{
inque[to]=true;
que.push(to);
}
}
}
}
if(dist[t]==INF) return -1;
int d=f;
for(int i=t; i!=s; i=prev[i])
d=min(d,gl[prev[i]][pree[i]].cap);
res+=d*dist[t];
f-=d;
for(int i=t; i!=s; i=prev[i])
{
int v=prev[i],e=pree[i];
gl[v][e].cap-=d;
gl[i][gl[v][e].rev].cap+=d;
}
}
return res;
}
int main()
{
while(scanf("%d",&n)&&n)
{
Init(n);
int m;
scanf("%d",&m);
int x,y,z;
while(m--)
{
scanf("%d%d%d",&x,&y,&z);
add_edge(y,x,1,z);
add_edge(x,y,1,z);
}
int ans=min_cost_flow(1,n,2);
if(ans==-1) puts("Back to jail");
else printf("%d\n",ans);
}
return 0;
}