POJ 2135 网络流MCMF入门题

来源:互联网 发布:空战 知乎 编辑:IT博客网 时间:2019/12/06 11:59

网络流MCMF入门题

题意:

​ n个点,m条边,现在要从1到n走两次,边只能经过一次,问最短的距离是多少。

思路:

​ 转化为网络流问题,对没一条边的最大流量为1,那么用次一次就是0,自然只能走一次。直接可以对f做出限制,相当于模板题,不过要注意的是sol.f和N,M的使用。

#include <iostream>#include <stdio.h>#include <cstring>#include <vector>#include <queue>#define INF 0x3f3f3f3fusing namespace std;const int maxn = 1005;struct Edge{    int from,to,cap,flow,cost;    Edge() {}    Edge(int a,int b,int c,int d,int e):from(a),to(b),cap(c),flow(d),cost(e) {}};struct MCMF{    int n,m,s,t,f;    vector<Edge> edges;    vector<int> g[maxn];    int inq[maxn];    int d[maxn];    int p[maxn];    int a[maxn];    void init(int n)    {        this->n =n;        for(int i=0; i<n; i++)g[i].clear();        edges.clear();    }    void addedge(int from,int to,int cap,int cost)    {        Edge e1= Edge(from,to,cap,0,cost), e2= Edge(to,from,0,0,-cost);        edges.push_back(e1);        edges.push_back(e2);        m=edges.size();        g[from].push_back(m-2);        g[to].push_back(m-1);    }    bool spfa(int s,int t, int & flow,int & cost)    {        for(int i=0; i<n; i++)            d[i]=INF;        memset(inq,0,sizeof(inq));        d[s]=0;        inq[s]=1;        p[s]=0;        a[s]=INF;        queue<int>q;        q.push(s);        while(!q.empty())        {            int u=q.front();            q.pop();            inq[u]=0;            for(int i=0; i<g[u].size(); i++)            {                Edge & e = edges[g[u][i]];                if(e.cap>e.flow && d[e.to]>d[u]+e.cost)                {                    d[e.to]=d[u]+e.cost;                    p[e.to]=g[u][i];                    a[e.to]=min(a[u],e.cap-e.flow);                    if(!inq[e.to])                    {                        q.push(e.to);                        inq[e.to]=1;                    }                }            }        }        if(d[t]==INF)            return false;        if(flow + a[t] >= f) {            cost += (f-flow)*d[t];            return false;        }        flow += a[t];        cost+=a[t]*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  MincostMaxflow(int s,int t)    {        int flow=0,cost =0;        while(spfa(s,t,flow,cost));        return cost;    }} sol;int M,N;int main(){    //freopen("in.txt","r",stdin);    while(scanf("%d%d",&N,&M) != EOF) {        sol.init(N);        for(int i = 1;i <= M; i++) {            int a,b,c;            scanf("%d%d%d",&a,&b,&c);            sol.addedge(a-1,b-1,1,c);            sol.addedge(b-1,a-1,1,c);        }        sol.f = 2;        int ans = sol.MincostMaxflow(0,N-1);        printf("%d\n",ans);    }    return 0;}
原创粉丝点击