2135_poj

来源:互联网 发布:淘宝商品管控部门 编辑:程序博客网 时间:2024/04/29 06:59
/* * 設從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;}