/* * 設從1到n的一條路徑為way1,從n到1的一條路徑為way2 * way1,way2中定點可相交,但是邊不可以,題意為min(way1+way2) * 這可以想成是最小費用最大流的問題,因為兩條路徑沒有邊的交集 * 可以設置原點到1的flow為2,n到匯點的flow也為2,因為每段路徑的邊 * 只能走一次,所以每個可以連接的點之間連接flow為1 * 費用則為題目給出的兩點之間的length,還要注意的一點是反向邊的cost * 必須為-cost,否則退流的時候是沒有辦法更新的 * 建圖: * src->1(flow = 2, cost = 0), n->des(flow = 2, cost = 0) * a->b(flow = 1, cost = cost) a->b 的反向邊(flow = 0, cost = -cost) * 實際上每兩個有鏈接的點都連上四條邊*/
/ * * Set the path from 1 to n way1, a path from n to 1 way2 * Way1, way2 sentinel can intersection, but the side may not the title means min (way1 + way2) * This can be thought of as the minimum cost maximum flow problem, because the side of the intersection of two paths * Origin can be set to 1 flow n to the Meeting Point of the flow is also 2, because each piece of the side of the path * Can only go once, so each point can be connected to the connection between the flow 1 * The cost is about $ topics given length between the two points, but also pay attention to is that the reverse side of the cost * Must-cost, or refund stream is no way to update * Built Figure: * Src-> 1 (flow = 2, cost = 0), n-> des (flow = 2, cost = 0) * A-> b (flow = 1, cost = cost), a-> b reverse side (flow = 0, cost = cost) * In fact, every two link points are connected on all four sides* /#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;#define MAXN 2001#define MAXM 50001#define INF 0x7ffffffstruct Edge { int v, cost, flow, next;}edge[MAXM];int e_cnt, head[MAXN], dis[MAXN], cur[MAXN], pre[MAXN], used[MAXN];void insert_arc(int u, int v, int cost, int flow){ edge[e_cnt].v = v; edge[e_cnt].cost = cost; edge[e_cnt].flow = flow; edge[e_cnt].next = head[u]; head[u] = e_cnt ++; swap(u, v); edge[e_cnt].v = v; edge[e_cnt].cost = -cost; edge[e_cnt].flow = 0; edge[e_cnt].next = head[u]; head[u] = e_cnt ++;}int spfa(int src, int des, int vn){ int u, v; queue<int> q; memset(used, 0, sizeof(used)); memset(pre, -1, sizeof(pre)); fill(dis, dis+vn+1, INF); q.push(src); used[src] = 1; dis[src] = 0; while( !q.empty() ) { u = q.front(); q.pop(); used[u] = 0; for(int i = head[u]; -1 != i; i = edge[i].next) { v = edge[i].v; if( !edge[i].flow ) { continue; } if( dis[v] > dis[u]+edge[i].cost ) { dis[v] = dis[u]+edge[i].cost; if( !used[v] ) { q.push(v); used[v] = 1; } cur[v] = i; pre[v] = u; } } } return dis[des];}int min_cost_max_flow(int src, int des, int vn){ int min_cost(0), each_cost(0), path_flow(INF), v; while( each_cost = spfa(src, des, vn) ) { if( INF == each_cost ) { return min_cost; } min_cost += each_cost; /*找當前路徑的flow*/ v = des; while( v != src ) { path_flow = min(path_flow, edge[cur[v]].flow); v = pre[v]; } /*更新增廣路*/ v = des; while( v != src ) { edge[cur[v]].flow -= path_flow; edge[cur[v]^0x1].flow += path_flow; v = pre[v]; } }}int main(int argc, char const *argv[]){#ifndef ONLINE_JUDGE freopen("test.in", "r", stdin);#endif int vertex, arc, u, v, w, src, des; while( ~scanf("%d %d", &vertex, &arc) ) { src = vertex+1; des = src+1; e_cnt = 0; memset(head, -1, sizeof(head)); for(int i = 0; i < arc; i ++) { scanf("%d %d %d", &u, &v, &w); insert_arc(u, v, w, 1); insert_arc(v, u, w, 1); } insert_arc(src, 1, 0, 2); insert_arc(vertex, des, 0, 2); printf("%d\n", min_cost_max_flow(src, des, des)); } return 0;}