zoukankan      html  css  js  c++  java
  • POJ 2135 Farm Tour

    问题:最小费用最大流
    思路:求最小费用最大流与求最大流的不同是最小费用最大流的模型的边上多了一个量cost,所以边上的表示为(flowi,costi),从S到T的最小费用最大流,每次从S到T找一条cost最小的路另加条件是flow不为0,则累加mincost+=minflow*costi,就这样循环知道找不到这样的最短路为止!该题需注意的是:加一个S点到1的flow为2,cost为0,,反向为flow为0,cost为0;加一个T点,n到T的flow为2,cost为0,反向为flow为0,cost为0;当输入数据内有边a-b的,则要添加两次边,每次都是添加正反边即添加a->b和b->a!哎,现在这个算法还不是太懂,只知道实现;算了,再做题研究研究吧!

    View Code
    #include <stdio.h>
    #include <memory.h>

    #define N 1002
    #define M 400002
    #define MAXVAL 1000000000
    #define MOV(x) (x=(x+1)%N)

    int nodevp[N];
    int nodeu[M],flow[M],cost[M],next[M],ind;
    int n,m,s,t;

    void addedge(int v,int u,int fw,int te)
    {
    nodeu[ind]=u;
    flow[ind]=fw;
    cost[ind]=te;
    next[ind]=nodevp[v];
    nodevp[v]=ind++;
    }

    void getDataAndBuildGraph()
    {
    int i,v,u,val;
    scanf("%d %d",&n,&m); s=0; t=n+1;

    memset(nodevp,-1,sizeof(nodevp)); ind=0;
    for(i=0;i<m;i++)
    {
    scanf("%d %d %d",&v,&u,&val);
    addedge(v,u,1,val);
    addedge(u,v,0,-val);
    addedge(u,v,1,val);
    addedge(v,u,0,-val);
    }
    addedge(s,1,2,0);
    addedge(1,s,0,0);
    addedge(n,t,2,0);
    addedge(t,n,0,0);
    }

    int dist[N],pre[N];
    int queue[N],inqueue[N],font,rear;

    int SPFA()
    {
    int i,v,u;

    for(i=0;i<=t;i++) dist[i]=MAXVAL; dist[s]=0;
    memset(pre,-1,sizeof(pre));
    memset(inqueue,0,sizeof(inqueue));
    font=rear=0; queue[MOV(rear)]=s; inqueue[s]=1;
    while(font!=rear)
    {
    v=queue[MOV(font)]; inqueue[v]=0;
    for(i=nodevp[v];~i;i=next[i])
    {
    u=nodeu[i];
    if(flow[i] && dist[u]>dist[v]+cost[i])
    {
    dist[u]=dist[v]+cost[i]; pre[u]=i;
    if(!inqueue[u]) queue[MOV(rear)]=u,inqueue[u]=1;
    }
    }
    }

    if(dist[t]!=MAXVAL) return 1;
    else return 0;
    }

    int mincost_maxflow()
    {
    int i,ans=0;

    while(SPFA())
    {
    ans+=dist[t];
    for(i=pre[t];~i;i=pre[nodeu[i^1]])
    {
    flow[i]--;
    flow[i^1]++;
    }
    }

    return ans;
    }

    void solve()
    {
    getDataAndBuildGraph();

    printf("%d\n",mincost_maxflow());
    }

    int main()
    {
    // freopen("input.txt","r",stdin);

    solve();

    return 0;
    }



  • 相关阅读:
    在eclipse中快速多行注释的方法
    Android开发:去掉Activity的头部标题栏及全屏显示
    C#的Process类的一些用法
    C#中隐式操作CMD命令行窗口 (转)
    我的INI 配置文件读写动态库
    Android高手进阶教程(五)之----Android 中LayoutInflater的使用!
    Android高手进阶教程(六)之----Android 中MenuInflater的使用(布局定义菜单)!
    Android Menu 之 optionsMenu 详解
    centos安装php扩展
    linux 权限
  • 原文地址:https://www.cnblogs.com/fornever/p/2426652.html
Copyright © 2011-2022 走看看