POJ-2195 最小费用最大流模板题

原创 2012年03月23日 16:03:58

     曾经看网络流~搞了最大流~搞了最小割..搞到最小费用最大流就卡住了..因为那时候不会SPFA..刚才拿过来看...感觉理解如何来求了..试着自己写了一个去A..就过了这道模板题..

     POJ2195的构图很简单了...其实最好的解法应该是KM..去年暑假就试着用KM写过这题..结果WA得一直不明不白..今天用网络流1A了...

    关于最小费用最大流的课件还是很多的...我目前的理解就是每次找起点到终点的最短路径做为增广路经来更新..直道找不到最短路径...而找最短路径就需要边的权值..初始时每条边的权值为该边单位流量费用..而在找到一条路径做剩余网络时..这条路径每条边做反向边,权值为正向单位流量费用的相反数...

     至于为什么要用SPFA而不能用Djikstra..是因为在做剩余网络时会出现负边...做SPFA..只有当边还有剩余的容量时才能更新...


Program: 

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<queue>
#define oo 2000000000
using namespace std;
struct node1
{
      int y,x;
}man[105],house[105];
struct node2
{
      int f,w;
}s[205][205];
struct node3
{
      int pre,w;
}dp[205];
int n,m,NumMan,NumHouse,ans;
char arc[105][105];
bool used[205],inqueue[205];
queue<int> myqueue;
bool SPFA()
{
      int h,k,i;
      while (!myqueue.empty()) myqueue.pop();
      memset(dp,-1,sizeof(dp));
      memset(inqueue,false,sizeof(inqueue));
      myqueue.push(0);  dp[0].w=0;      
      while (!myqueue.empty())
      {
             h=myqueue.front();
             myqueue.pop();
             inqueue[h]=false;
             for (i=0;i<=n;i++)
             if (s[h][i].f && (dp[i].pre==-1 || dp[i].w>dp[h].w+s[h][i].w))
             {
                     dp[i].w=dp[h].w+s[h][i].w;
                     dp[i].pre=h;
                     if (!inqueue[i])
                     {
                            inqueue[i]=true;
                            myqueue.push(i);
                     }
             }
      }
      if (dp[n].pre==-1) return false;
      return true;
}
void MinCostOfMaxFlow()
{
      int i,m,way[205],Flow;
      ans=0;
      while (SPFA())
      {
            m=0;
            i=n;
            memset(way,0,sizeof(way));
            while (1)
            {
                  way[++m]=i;
                  if (!i) break;
                  i=dp[i].pre;
            }
            Flow=oo;
            for (i=1;i<m;i++) 
               if (s[way[i+1]][way[i]].f<Flow) Flow=s[way[i+1]][way[i]].f;
            for (i=1;i<m;i++)
            {
                  ans+=s[way[i+1]][way[i]].w*Flow;
                  s[way[i+1]][way[i]].f-=Flow;
                  s[way[i]][way[i+1]].f+=Flow;
                  s[way[i]][way[i+1]].w=-s[way[i+1]][way[i]].w;
            } 
      }
}
int absI(int x)
{
      if (x<0) return -x;
      return x;
}
int main()
{
      freopen("input.txt","r",stdin);
      freopen("output.txt","w",stdout);
      int i,j;
      while (~scanf("%d%d\n",&n,&m))
      {
            if (!n && !m) break;
            for (i=1;i<=n;i++) gets(arc[i]+1);
            NumMan=NumHouse=0;
            for (i=1;i<=n;i++)
               for (j=1;j<=m;j++)
                  if (arc[i][j]=='m')
                  {
                         NumMan++;
                         man[NumMan].y=i;
                         man[NumMan].x=j;                                     
                  }else
                  if (arc[i][j]=='H')
                  {
                         NumHouse++;
                         house[NumHouse].y=i;
                         house[NumHouse].x=j;
                  } 
            memset(s,0,sizeof(s));
            for (i=1;i<=NumMan;i++)
               for (j=1;j<=NumHouse;j++)
               {
                      s[i][j+NumMan].f=1;
                      s[i][j+NumMan].w=absI(man[i].x-house[j].x)+absI(man[i].y-house[j].y); 
               }
            for (i=1;i<=NumMan;i++)
            {
                    s[0][i].f=1;
                    s[0][i].w=0; 
            }
            for (i=1;i<=NumHouse;i++)
            {
                    s[i+NumHouse][NumMan+NumHouse+1].f=1;
                    s[i+NumHouse][NumMan+NumHouse+1].w=0;
            }
            n=NumMan+NumHouse+1;  
            MinCostOfMaxFlow();
            printf("%d\n",ans);            
      }
      return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

POJ 2195 Going Home 最小费用最大流(模板题)

以下来自点击打开链接 最小费用最大流     通过EK,Dinic,ISAP算法可以得到网络流图中的最大流,一个网络流图中最大流的流量max_flow是唯一的,但是达到最大流量ma...

POJ 2195 Going Home -- 最小费用最大流模板

裸题。。。 第一次过还是纪念下,模板还是自己写的用起来舒服些。。#include #include #include #include #include #include #includ...

POJ 2195 Going Home (最小费用最大流)

题目链接 第一次写最小费用最大流 最小费用最大流相当于最短路和最大流的结合,建立了残量图后,费用作为距离 然后bfs遍历源点到汇点的最小费用,用数组记录遍历路径,而后通过最大流的做法 对残量图...
  • HHH_go_
  • HHH_go_
  • 2016年12月12日 16:57
  • 167

poj 2195 going home(最小费用最大流)

题目链接:http://poj.org/problem?id=2195 Description On a grid map there are n little men and n houses....
  • txgANG
  • txgANG
  • 2016年11月16日 17:53
  • 137

POJ 2195 Going Home (最小费用最大流)

Description On a grid map there are n little men and n houses. In each unit time, every little man...

POJ 2195:Going Home(SPFA最小费用最大流)

B - Going Home Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit...

POJ-2195 Going Home (最小费用最大流初学 && 最大权二分匹配—KM算法)

Going Home 最小费用最大流 && 最大权二分匹配,两种解法 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions:...

POJ 2195 Going Home (最佳完美匹配, 最小费用最大流)

题目类型  最优比率生成树 题目意思 给出最多 1000 个点与这些点之间的边的长度与花费 找一棵生成树 使  Sum(边的花费) / Sum(边的长度) 的值最小 输出这个值 ...

POJ2195-Going Home(最小费用最大流)

题目链接http://poj.org/problem?id=2195题意一个N * M的地图,由.(空地)和H(房子)和m(人)组成,其中人的数目等于房子的数目,要求将每个人位移到不同的房子里面 ,要...
  • Lzedo
  • Lzedo
  • 2016年08月18日 11:56
  • 93

poj2195——Going Home(最小费用最大流)

DescriptionOn a grid map there are n little men and n houses. In each unit time, every little man ca...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ-2195 最小费用最大流模板题
举报原因:
原因补充:

(最多只允许输入30个字)