POJ 2135 Farm Tour 费用流

来源:互联网 发布:淘宝助理发件人设置 编辑:程序博客网 时间:2024/05/16 23:47

题意:有N个点,M条路。起点为1,终点为N,要求从起点出发,到达终点,再返回起点,同时每条路只能经过一次。求出整个路线的最短总长度。

思路:如果只考虑来和回的话,这个问题只是无向图中两点的最短路问题。

          如果先计算去时的最短路,删掉这些路再求剩余图的最短路,行不行呢?我们可以找到反例。换句话说,我们来和回分别贪心的方法是错误的。我们需要后悔!

         这个时候就需要网络流了。我们将问题转化为从1号顶点到N号顶点的两条没有公共边的路径。这样我们就是就流量为2的最小费用流。

代码如下:

#include <cstdio>#include <algorithm>#include <cstring>using namespace std;struct edge{    int from,to,cap,flow,cost;    edge(int u = 0,int v = 0, int c= 0,int f = 0, int w = 0):    from(u),to(v),cap(c),flow(f),cost(w){}};struct mcmf{    int n,m,s,t;    static const int MAX = 50000;    static const int INF = 0x3f3f3f3f;    edge edges[4 * MAX];    int head[MAX];    int next[MAX];    int tot;    int que[MAX],front,tail;    bool inq[MAX];    int d[MAX];    int p[MAX];    int a[MAX];    void init(){        memset(head,-1,sizeof(head));        tot = 0;    }    void addedge(int from, int to, int cap, int cost){        edges[tot] = edge(from,to,cap,0,cost);        next[tot] = head[from],head[from] = tot++;        edges[tot] = edge(to,from,0,0,-cost);        next[tot] = head[to],head[to] = tot++;    }    bool bellmanford(int s, int t,int & flow, int &cost){        memset(d,0x3f,sizeof(d));        memset(inq,false,sizeof(inq));        d[s] = 0,inq[s] = true,p[s] = 0,a[s] = INF;        front = tail = 0;        que[tail++] = s;        while(front < tail){            int u = que[front++];inq[u] = false;            for(int v = head[u]; v != -1; v = next[v]){                edge & e = edges[v];                if(e.cap > e.flow && d[e.to] > d[u] + e.cost){                    d[e.to] = d[u] + e.cost;                    p[e.to] = v;                    a[e.to] = min(a[u],e.cap - e.flow);                    if(!inq[e.to])                        que[tail++] = e.to,inq[e.to] = true;                }            }        }        if(d[t] == INF) return false;        flow += a[t]; cost += d[t];        for(int u = t; u != s; u = edges[p[u]].from){            edges[p[u]].flow += a[t];            edges[p[u]^1].flow -=a[t];        }        return true;    }    int mincost(int s,int t){        int flow = 0,cost = 0;        while(bellmanford(s,t,flow,cost));        return cost;    }} solver;int main(void){    //freopen("input.txt","r",stdin);    int N,M;    int u,v,c;    scanf("%d %d",&N, &M);    solver.init();    int s = 0, t = N + 1;    solver.addedge(s,1,2,0);    solver.addedge(N,t,2,0);    for(int i = 0 ; i < M; ++i){        scanf("%d %d %d", &u,&v,&c);        solver.addedge(u,v,1,c);        solver.addedge(v,u,1,c);    }    printf("%d\n",solver.mincost(s,t));    return 0;}

0 0
原创粉丝点击