POJ 2135 Farm Tour(最小费用最大流E'K')

版权声明:get busy living...or get busy dying https://blog.csdn.net/qq_41444888/article/details/88724667

最小费用最大流:保证最大流的同时使得费用最小

这道题要求从1-n和n-1总的最短路径,模拟每条路流量为1,费用为路径长度,用spfa进行处理,并设置源点和汇点(费用0,流量2),模拟最小费用最大流

E'K'算法(把EK的bfs寻路换成spfa即可)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#define ll long long
#define mod 1000000007
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1005;
const int maxm = 40005;
bool vis[maxn];
int pre[maxn], d[maxn], head[maxn];
int cnt;
int n, m;
int u, v, w, c;
int s, t;
struct node
{
    int s, to, next, w, c;
}e[maxm];
void init()
{
    memset(head, - 1, sizeof(head));
    s = n + 1, t = n + 2;
    cnt = 0;
}
void addedge(int u, int v, int w, int c)//w是路径花费,c是流量
{
    e[cnt].s = u;
    e[cnt].to = v;
    e[cnt].w = w;
    e[cnt].c = c;
    e[cnt].next = head[u];
    head[u] = cnt ++;

    e[cnt].s = v;
    e[cnt].to = u;
    e[cnt].w = -w;
    e[cnt].c = 0;
    e[cnt].next = head[v];
    head[v] = cnt ++;
}
bool spfa()
{
    memset(vis, 0, sizeof(vis));
    memset(pre, -1, sizeof(pre));
    memset(d, 0x3f, sizeof(d));
    queue<int> q;
    q.push(s);
    d[s] = 0;
    vis[s] = 1;
    while(! q.empty())
    {
        int h = q.front();
        q.pop();
        vis[h] = 0;
        for(int i = head[h]; ~i; i = e[i].next)
        {
            if(e[i].c)
            {
                int v = e[i].to;
                if(d[h] + e[i].w < d[v])
                {
                    d[v] = d[h] + e[i].w;
                    pre[v] = i;
                    if(! vis[v])
                    {
                        vis[v] = 1;
                        q.push(v);
                    }
                }
            }
        }
    }
    if(d[t] == inf) return 0;
    else return 1;
}
int EK()
{
    int cost = 0;
    int tt, minc;
    while(spfa())
    {
        tt = t;
        minc = inf;
        while(pre[tt] != -1)
        {
            minc = min(e[pre[tt]].c, minc);
            tt = e[pre[tt]].s;
        }
        tt = t;
        while(pre[tt] != -1)
        {
            e[pre[tt]].c -= minc;
            e[pre[tt]^1].c += minc;
            tt = e[pre[tt]].s;
        }
        cost += d[t] * minc;
    }
    return cost;
}
int main()
{
    while(scanf("%d%d", &n, &m) != EOF)
    {
        init();
        for(int i = 1; i <= m; i ++)
        {
            scanf("%d%d%d", &u, &v, &w);
            addedge(u, v, w, 1);
            addedge(v, u, w, 1);
        }
        addedge(s, 1, 0, 2);
        addedge(n, t, 0, 2);
        printf("%d\n", EK());
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41444888/article/details/88724667