Farm tour
Question:
John has n places, his home is in No. 1, and N is a warehouse. There are m roads (two-way) in the farm. road I connects the Ai Site and Bi site with a length of Ci. John wants to depart from his home, arrive at the warehouse after several places, and return to his home. If you want to make a round trip that cannot go through the same road twice, find the minimum length of the tour route.
Algorithm analysis:
Is it feasible to use the shortest path to solve the problem and then delete the edges in the first Shortest Path to solve the problem? We should be able to find the counterexample immediately to prove that this method cannot always get the optimal result.
So we gave up the idea of removing and returning the problem. Instead, we thought of the problem as how to find two paths without public edges from vertex 1 to vertex N? After this conversion, it is not the minimum cost for the traffic of 2, because the road is bidirectional.
#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <cstdio>#include <cstring>using namespace std;/* 流量限制为f下,求解最小费用 时间复杂度:O(F mlogn) */typedef pair<int,int> P;const int INF = 1 << 30;const int MAXN = 1000 + 10;struct Edge{ int to,cap,cost,rev; Edge(){}; Edge(int _to,int _cap,int _cost,int _rev) :to(_to),cap(_cap),cost(_cost),rev(_rev){};};int V; //顶点int N,M,S,T;vector<Edge> G[MAXN];int h[MAXN]; //顶点的势int dist[MAXN]; //最短距离int prevv[MAXN],preve[MAXN]; //最短路中德前驱节点和对应的边void init(){ S = 1; T = N; V = T + 1; for(int i = 0;i <= V;++i) G[i].clear();}//增加一条从from到to容量为cap费用为cost的边void addEdge(int from,int to,int cap,int cost){ G[from].push_back(Edge(to,cap,cost,G[to].size())); G[to].push_back(Edge(from,0,-cost,G[from].size() - 1));}//求解从s到t流量为f的最小费用流//如果没有流量为f的流,则返回-1int min_cost_flow(int s,int t,int f){ //s:起点 t:终点 f:流量限制 int res = 0; fill(h,h + V,0); //初始化h while(f > 0){ //使用Dijkstra算法更新h priority_queue<P,vector<P>,greater<P> > Q; fill(dist,dist + V,INF); dist[s] = 0; Q.push(P(0,s)); while(!Q.empty()){ P p = Q.top(); Q.pop(); int v = p.second; if(dist[v] < p.first) continue; for(int i = 0;i < G[v].size();++i){ Edge& e = G[v][i]; int tmp = dist[v] + e.cost + h[v] - h[e.to]; if(e.cap > 0 && dist[e.to] > tmp){ dist[e.to] = tmp; prevv[e.to] = v; preve[e.to] = i; Q.push(P(dist[e.to],e.to)); } } } //while //不能增广 if(dist[t] == INF){ return -1; } for(int v = 1;v <= V;++v) h[v] += dist[v]; int d = f; for(int v = t;v != s;v = prevv[v]){ d = min(d,G[prevv[v]][preve[v]].cap); } f -= d; res += d * h[t]; for(int v = t; v != s;v = prevv[v]){ Edge& e = G[prevv[v]][preve[v]]; e.cap -= d; G[v][e.rev].cap += d; } } return res;}int main(){ //freopen("Input.txt","r",stdin); while(~scanf("%d%d",&N,&M)){ init(); int a,b,c; for(int i = 0;i < M;++i){ scanf("%d%d%d",&a,&b,&c); addEdge(a,b,1,c); addEdge(b,a,1,c); } printf("%d\n",min_cost_flow(S,T,2)); } return 0;}
Poj farm tour