模板题 poj 2135 Farm Tour

来源:互联网 发布:动漫网站源码 编辑:程序博客网 时间:2024/06/08 16:32

 最小费用最大流  


有两个地方没搞懂 需要接下来研究一下 。。。


#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <queue>#include <stack>#include <map>#include <limits.h>using namespace std;const int inf=1e8-1;const int eMax=4e4+5;   //边数const int nMax=10002;   //顶点数struct{    int v, cap, cost, next, re;    //  re记录逆边的下标。} edge[eMax];int n, m, ans;int k, edgeHead[nMax];int que[nMax], pre[nMax], dis[nMax];bool vis[nMax];void add(int u, int v, int ca, int co){    edge[k].v = v;    edge[k].cap = ca;    edge[k].cost = co;    edge[k].next = edgeHead[u];    edge[k].re = k + 1;    edgeHead[u] = k ++;    edge[k].v = u;    edge[k].cap = 0;    edge[k].cost = -co;    edge[k].next = edgeHead[v];    edge[k].re = k - 1;    edgeHead[v] = k ++;}bool spfa()                   //  源点为0,汇点为n。{    int i, head = 0, tail = 1;    for(i = 0; i <= n; i ++)    {        dis[i] = inf;        vis[i] = false;    }    dis[0] = 0;    que[0] = 0;    vis[0] = true;    while(tail > head)        //  这里最好用队列,有广搜的意思,堆栈像深搜。    {        int u = que[head ++];        for(i = edgeHead[u]; i != 0; i = edge[i].next)        {            int v = edge[i].v;            if(edge[i].cap && dis[v] > dis[u] + edge[i].cost)            {                dis[v] = dis[u] + edge[i].cost;                pre[v] = i;                if(!vis[v])                {                    vis[v] = true;                    que[tail ++] = v;                }            }        }        vis[u] = false;    }    if(dis[n] == inf) return false;    return true;}void end(){    int u, p, sum = inf;    for(u = n; u != 0; u = edge[edge[p].re].v)    {        p = pre[u];        sum = min(sum, edge[p].cap);    }    for(u = n; u != 0; u = edge[edge[p].re].v)    {        p = pre[u];        edge[p].cap -= sum;        edge[edge[p].re].cap += sum;        ans += sum * edge[p].cost;     //  cost记录的为单位流量费用,必须得乘以流量。    }}int main(){    while(~scanf("%d%d",&n,&m))    {        k=1;        for(int i=0; i<m; i++)        {            int a,b,c;            scanf("%d%d%d",&a,&b,&c);            add(a,b,1,c);            add(b,a,1,c);  //不明白为什么要建两次边~~~        }        add(0,1,2,0);        n++;        add(n-1,n,2,0);        ans = 0;        while(spfa())        {            end();        }        printf("%d\n",ans);  //ans为最小费用, 那最大流的结果怎么表示呢?    }    return 0;}


0 0
原创粉丝点击