Problem, in short Given a weighed, undirected graph, find the shortest path from S to T and back without using the same edge twice.
很基础的费用网络流
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<vector> #define LL long long #define maxn 1024 using namespace std; <<; struct Edge{ int from,to,dist,flow,cap; }; int n,m,d[maxn],a[maxn],inq[maxn],p[maxn]; vector<Edge> edges; vector<int> G[maxn]; void addEdge(int from,int to,int dist){ edges.push_back((Edge){,}); edges.push_back((Edge){to,,}); int m=edges.size(); G[); G[to].push_back(m-); } void connect(){ edges.push_back((Edge){,n+,,,}); edges.push_back((Edge){n+,,,,}); int m=edges.size(); G[].push_back(m-); G[n+].push_back(m-); edges.push_back((Edge){n+,,,,}); edges.push_back((Edge){,n+,,,}); m+=; G[n+].push_back(m-); G[].push_back(m-); edges.push_back((Edge){n,n+,,,}); edges.push_back((Edge){n+,n,,,}); m+=; G[n].push_back(m-); G[n+].push_back(m-); edges.push_back((Edge){n+,n,,,}); edges.push_back((Edge){n,n+,,,}); m+=; G[n+].push_back(m-); G[n].push_back(m-); } bool BF(int s,int t,int &flow,int &cost){ memset(inq,,sizeof(inq)); ;i<=n+;i++) d[i]=inf; inq[s]=;d[s]=;a[s]=inf; queue<int> Q; Q.push(s); while(!Q.empty()){ int u=Q.front();Q.pop(); inq[u]=; ;i<G[u].size();i++){ Edge &e=edges[G[u][i]]; if(e.cap>e.flow&&d[e.to]>d[u]+e.dist){ d[e.to]=d[u]+e.dist; a[e.to]=min(a[u],e.cap-e.flow); p[e.to]=G[u][i]; if(!inq[e.to]){ inq[e.to]=; Q.push(e.to); } } } } if(d[t]>=inf) return false; flow+=a[t]; cost+=a[t]*d[t]; int u=t; for(;u!=s;u=edges[p[u]].from){ edges[p[u]].flow+=a[t]; edges[p[u]^].flow-=a[t]; } return true; } void init(){ edges.clear(); ;i<=n+;i++) G[i].clear(); } int main() { while(scanf("%d",&n)&&n){ scanf("%d",&m); init(); int x,y,d; ;i<=m;i++){ scanf("%d%d%d",&x,&y,&d); addEdge(x,y,d);addEdge(y,x,d); } connect(); ,cost=; ,n+,flow,cost)); ){ puts("Back to jail"); }else{ printf("%d\n",cost); } } ; }