POJ-2195 最小费用最大流模板题
来源:互联网 发布:sai软件无毒下载 编辑:程序博客网 时间:2024/06/06 00:04
曾经看网络流~搞了最大流~搞了最小割..搞到最小费用最大流就卡住了..因为那时候不会SPFA..刚才拿过来看...感觉理解如何来求了..试着自己写了一个去A..就过了这道模板题..
POJ2195的构图很简单了...其实最好的解法应该是KM..去年暑假就试着用KM写过这题..结果WA得一直不明不白..今天用网络流1A了...
关于最小费用最大流的课件还是很多的...我目前的理解就是每次找起点到终点的最短路径做为增广路经来更新..直道找不到最短路径...而找最短路径就需要边的权值..初始时每条边的权值为该边单位流量费用..而在找到一条路径做剩余网络时..这条路径每条边做反向边,权值为正向单位流量费用的相反数...
至于为什么要用SPFA而不能用Djikstra..是因为在做剩余网络时会出现负边...做SPFA..只有当边还有剩余的容量时才能更新...
Program:
#include<iostream>#include<string.h>#include<stdio.h>#include<queue>#define oo 2000000000using 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 最小费用最大流模板题
- poj-2195-Going Home(最小费用最大流模板题)
- POJ 2195 Going Home 最小费用最大流(模板题)
- 最小费用最大流模板 poj 2159 模板水题
- poj 2135最小费用最大流模板
- 最小费用最大流模板 poj 2135
- POJ 2195 Going Home -- 最小费用最大流模板
- poj 2135 最小费用最大流模板题
- poj 2135 最小费用最大流模板题
- poj 2135 Farm Tour 最小费用最大流模板题
- 最小费用最大流模板题
- 模板[最小费用最大流]
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流,模板
- 最小费用最大流模板
- 最小费用最大流 模板
- Java基本类型
- 用ASP.NET with C# 绘制曲线图(Curve图)
- Windows系统环境变量大全
- Java英文面试题(核心知识篇)
- Sql Server临时表
- POJ-2195 最小费用最大流模板题
- Access打开出现正在准备安装,正在配置报错的解决办法
- 模板 n维矩阵的二分幂
- Insight into eDir-CMS (Composed by Wing and EA) - 2
- Struts运行机制
- sql 百万级数据库优化方案
- JAVA英文面试题(15道)
- 【Android.mk】android编译系统makefile文件Android.mk的写法
- 在cmd中FOR的用法