POJ 2135 Farm Tour(费用流)

来源:互联网 发布:荷兰红灯区知乎 编辑:程序博客网 时间:2024/06/05 07:38

题目大意:有一个人要从点1出发,走到点n,然后再走回点1,其中不重复走同一条边,问走过的最短路是多少

解题思路:用费用流做的话,费用就是边权了,而容量就是1了
因为是双向边,所以拆成两条有向边的费用都是边权
因为不能重复走,所以找到一条边后,要将另一条边的费用变为负值,这样重复走的话,就可以将以前的边给抵消了
这题还可以用最短路做,具体的我这篇博客有说到UVA - 10806 Dijkstra, Dijkstra.

#include <cstdio>#include <cstring>#include <queue>#include <vector>#include <algorithm>using namespace std;const int MAXNODE = 1010;const int MAXEDGE = 20010;typedef int Type;const Type INF = 0x3f3f3f3f;struct Edge{    int u, v, next;    Type cap, flow, cost;    Edge() {}    Edge(int u, int v, Type cap, Type flow, Type cost, int next): u(u), v(v), cap(cap), flow(flow), cost(cost), next(next) {}};struct MCMF{    int n, m, s, t;    Edge edges[MAXEDGE];    int head[MAXNODE];    int p[MAXNODE];    Type d[MAXNODE];    Type a[MAXNODE];    bool inq[MAXNODE];    void init(int n) {        this->n = n;        memset(head, -1, sizeof(head));        m = 0;    }    void AddEdge(int u, int v, Type cap, Type cost) {        edges[m] = Edge(u, v, cap, 0, cost, head[u]);        head[u] = m++;        edges[m] = Edge(v, u, cap, 0, cost, head[v]);        head[v] = m++;    }    bool BellmanFord(int s, int t, Type &flow, Type &cost) {        for (int i = 0; i < n; i++) d[i] = INF;        memset(inq, 0, sizeof(inq));        d[s] = 0; inq[s] = true; p[s] = 0; a[s] = INF;        queue<int> Q;        Q.push(s);        while (!Q.empty()) {            int u = Q.front(); Q.pop();            inq[u] = false;            for (int i = head[u]; ~i; i = edges[i].next) {                Edge &e = edges[i];                if (e.cap > e.flow && d[e.v] > d[u] + e.cost) {                    d[e.v] = d[u] + e.cost;                    p[e.v] = i;                    a[e.v] = min(a[u], e.cap - e.flow);                    if (!inq[e.v]) {                         Q.push(e.v); inq[e.v] = true;                    }                }             }        }        if (d[t] == INF) return false;        flow += a[t];        cost += a[t] * d[t];        int u = t;        while (u != s) {            edges[p[u]].flow += a[t];            edges[p[u] ^ 1].cost = -edges[p[u] ^ 1].cost;            u = edges[p[u]].u;        }        return true;    }    Type MinCost(int s, int t) {        this->s = s; this->t = t;        Type flow = 0, cost = 0;        while (BellmanFord(s, t, flow, cost));        return cost;    }}mcmf;int n, m;void init() {    int source = 1, sink = n;    mcmf.init(n + 2);    int u, v, c;    for (int i = 0; i < m; i++) {        scanf("%d%d%d", &u, &v, &c);        mcmf.AddEdge(u, v, 1, c);    }    mcmf.AddEdge(0, source, 2, 0);    mcmf.AddEdge(sink, n + 1, 2, 0);    printf("%d\n", mcmf.MinCost(0, n + 1));}int main() {    while (scanf("%d%d", &n, &m) != EOF) {        init();    }    return 0;}
0 0
原创粉丝点击