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;
}


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

POJ2195-Going Home

转载请注明出处:優YoU http://blog.csdn.net/lyy289065406/article/details/6732762   大致题意: 给定一个N*M的地图,地图上有若干个...
  • lyy289065406
  • lyy289065406
  • 2011年08月30日 15:40
  • 6286

POJ 2195(费用流)

POJ 2195题目大意给你一个N∗M​N*M​的地图,上面有房子”H”,人“m”,空地“.”。房子和人数相同,将人移动一格花费为1,问将将地图变为一个房子上恰好一人的最小花费。(在移动的过程中可以出...
  • mmy1996
  • mmy1996
  • 2017年02月21日 17:04
  • 591

POJ 3680 最小费用最大流

思路:这题建图比较机智,我刚开始想到能建的图也就是离散化后两个端点连边,流量为1,费用为负的权值(因为求的是最大费用最大流),然后再加上源点和汇点,也就如此而已;但是这样建图样例第二和第四个不正确,因...
  • u011466175
  • u011466175
  • 2014年08月26日 14:43
  • 1025

POJ 2135 Farm Tour(最小费用最大流 模板题)

POJ 2135 Farm Tour(最小费用最大流 模板题)
  • u012860063
  • u012860063
  • 2014年12月10日 21:33
  • 1371

poj2195 - Going Home

想看更多的解题报告:http://blog.csdn.net/wangjian8006/article/details/7870410                                ...
  • wangjian8006
  • wangjian8006
  • 2012年09月04日 09:02
  • 1240

POJ2195 Going Home

最小费用最大流
  • H992109898
  • H992109898
  • 2016年04月29日 20:21
  • 230

poj 2135 Farm Tour 最小费用最大流模板题

传送门:poj 2135 Farm Tour 描述: Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submi...
  • guhaiteng
  • guhaiteng
  • 2016年08月30日 23:41
  • 885

ACM hdu5352 最小费用最大流 模板 网络流

先建图,求字典序最小,转化成前面的费用较大,的费用流 for (int i=0; i 2015多校第5场-hdu5352 起初用ISAP最大流WA了,再后来用了费用流模板TLE,最后使用了大白书...
  • nickwong_
  • nickwong_
  • 2015年08月04日 20:44
  • 1665

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

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

poj2195

跟上题变化实在是太小了,直接套用模板即可!建图都几乎如出一辙。 #include #include #include #include using namespace std; #def...
  • zhengnanlee
  • zhengnanlee
  • 2014年03月13日 16:12
  • 955
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ-2195 最小费用最大流模板题
举报原因:
原因补充:

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