uva 1658 Admiral 最小费最大流

来源:互联网 发布:无锡编程培训学校 编辑:程序博客网 时间:2024/04/25 07:55

题意就是让你求两次1到n的最短路。这题应该可以用最短路来求解吧,只需要将第一次用到的边删去即可。我这里是按照算法竞赛入门经典里面提到拆点+最小费最大流。

#include<bits/stdc++.h>using namespace std;const int N=1024*4;const int inf=1<<24;struct Edge{    int from,to,cap,flow,cost;};vector<Edge>edges;vector<int>G[N];int n,m;int inq[N],p[N],d[N],a[N];void AddEdge(int from, int to,int cap, int cost){    Edge tp;    tp.from=from,tp.to=to,tp.cap=cap,tp.flow=0,tp.cost=cost;    edges.push_back(tp);    tp.from=to,tp.to=from,tp.cap=0,tp.flow=0,tp.cost=-cost;    edges.push_back(tp);    int g=edges.size();    G[from].push_back(g-2);    G[to].push_back(g-1);}int BellmanFord(int s,int t,int &flow, int &cost){    int i,j,u;    for(i=0; i<N; i++) d[i]=inf;    memset(inq,0,sizeof(inq));    d[s]=0;    inq[s]=1;    p[s]=1;    a[s]=inf;    queue<int>Q;    Q.push(s);    while(!Q.empty())    {        u=Q.front();        Q.pop();        inq[u]=0;        for(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 0;    flow+=a[t];    cost+=d[t]*a[t];    u=t;    while(u!=s)    {        edges[p[u]].flow+=a[t];        edges[p[u]^1].flow-=a[t];        u=edges[p[u]].from;    }    return 1;}int Mincost(int s,int t){    int flow=0,cost=0;    BellmanFord(s,t,flow,cost);    return cost;}int main(){    int i,u,v,c;    while(~scanf("%d%d",&n,&m))    {        for(i=0; i<N; i++) G[i].clear();        edges.clear();        for(i=2; i<n; i++)        {            AddEdge(i,i+n,1,0);        }        for(i=0; i<m; i++)        {            scanf("%d%d%d",&u,&v,&c);            if(u==1||u==n) AddEdge(u,v,1,c);            else AddEdge(u+n,v,1,c);        }        int ans=0;        ans+=Mincost(1,n);        ans+=Mincost(1,n);        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击