POJ - 2135 -- Farm Tour (费用流SPFA实现)

题目来源:http://poj.org/problem?id=2135

Dijkstra算法实现:https://blog.csdn.net/moon_sky1999/article/details/81360017

抽象为每条边的费用为边的长度,流量为1,这样即是求1-n流量为2的最小费用流。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int maxm=1e5+10;
const int maxn=1e4+10;
int n,m;
int cnt,head[maxn],dis[maxn],prevv[maxn],preve[maxn];
struct edge {
    int to, next, cap, cost, rev;
}e[maxm];
void ins(int x,int y,int z,int c) {
    e[++cnt].to = y;
    e[cnt].next = head[x];
    head[x] = cnt;
    e[cnt].cap = z;
    e[cnt].rev = cnt + 1;
    e[cnt].cost = c;
    e[++cnt].to = x;
    e[cnt].next = head[y];
    head[y] = cnt;
    e[cnt].cap = 0;
    e[cnt].rev = cnt - 1;
    e[cnt].cost = -c;
}
int min_cost_flow(int s,int t,int f) {
    int ans = 0;
    while (f > 0) {
        memset(dis, 63, sizeof(dis));
        queue<int> q;
        q.push(s);
        dis[s] = 0;
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            if (dis[v] > 1e8)continue;
            for (int i = head[v]; i; i = e[i].next) {
                if (e[i].cap > 0 && dis[e[i].to] > dis[v] + e[i].cost) {
                    dis[e[i].to] = dis[v] + e[i].cost;
                    prevv[e[i].to] = v;
                    preve[e[i].to] = i;
                    q.push(e[i].to);
                }
            }
        }
        if (dis[t] > 1e8)
            return -1;
        int d = f;
        for (int i = t; i != s; i = prevv[i]) {
            d = min(d, e[preve[i]].cap);
        }
        f -= d;
        ans += d * dis[t];
        for (int i = t; i != s; i = prevv[i]) {
            e[preve[i]].cap -= d;
            e[e[preve[i]].rev].cap += d;
        }
    }
    return ans;
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    while (cin >> n >> m) {
        cnt = 0;
        memset(head, 0, sizeof(head));
        memset(preve, 0, sizeof(preve));
        memset(prevv, 0, sizeof(prevv));
        for (int i = 1; i <= m; ++i) {
            int x, y, z;
            cin >> x >> y >> z;
            ins(x, y, 1, z);
            ins(y, x, 1, z);
        }
        cout << min_cost_flow(1, n, 2) << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/moon_sky1999/article/details/81360328