POJ - 2195 Going Home(最小费用最大流)
2015-11-25 21:05
513 查看
1、N*M的矩阵中,有k个人和k个房子,每个人分别进入一个房子中,求所有人移动的最小距离。
2、人看成源点,房子看成汇点,求最小费用最大流。
建图--
人指向房子,容量为1,费用为人到房子的曼哈顿距离。
建立超级源点和超级汇点:超级源点指向人,容量为1,费用为0;房子指向超级汇点,容量为1,费用为0。
求超级源点到超级汇点的最小费用最大流即可。
ps:容量为什么都设为1?---有待研究。。
今天又看了下,设为1是必须的。
超级源点指向人,容量为1,保证人这个点只有一个人;
房子指向超级汇点,容量为1,保证一个房子只能容纳一个人。
然而,人指向房子,容量为1,这并不是必须的,因为前两个条件已经足够了。为了简单,这里仍然把这个容量设为1。
3、
1、Bellman-Ford:
View Code
2、人看成源点,房子看成汇点,求最小费用最大流。
建图--
人指向房子,容量为1,费用为人到房子的曼哈顿距离。
建立超级源点和超级汇点:超级源点指向人,容量为1,费用为0;房子指向超级汇点,容量为1,费用为0。
求超级源点到超级汇点的最小费用最大流即可。
ps:容量为什么都设为1?---有待研究。。
今天又看了下,设为1是必须的。
超级源点指向人,容量为1,保证人这个点只有一个人;
房子指向超级汇点,容量为1,保证一个房子只能容纳一个人。
然而,人指向房子,容量为1,这并不是必须的,因为前两个条件已经足够了。为了简单,这里仍然把这个容量设为1。
3、
1、Bellman-Ford:
/* zkw费用流 对于二分图类型的比较高效 */ #include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MAXN=256; const int MAXM=20500; const int INF=0x3f3f3f3f; struct Edge{ int to,next,cap,flow,cost; Edge(int _to=0,int _next=0,int _cap=0,int _flow=0,int _cost=0): to(_to),next(_next),cap(_cap),flow(_flow),cost(_cost){} }edge[MAXM]; struct ZKW_MinCostMaxFlow{ int head[MAXN],tot; int cur[MAXN]; int dis[MAXN]; bool vis[MAXN]; int ss,tt,N;//源点、汇点和点的总个数(编号是0~N-1),不需要额外赋值,调用会直接赋值 int min_cost,max_flow; void init(){ tot=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int cap,int cost){ edge[tot]=Edge(v,head[u],cap,0,cost); head[u]=tot++; edge[tot]=Edge(u,head[v],0,0,-cost); head[v]=tot++; } int aug(int u,int flow){ if(u==tt)return flow; vis[u]=true; for(int i=cur[u];i!=-1;i=edge[i].next){ int v=edge[i].to; if(edge[i].cap>edge[i].flow&&!vis[v]&&dis[u]==dis[v]+edge[i].cost){ int tmp=aug(v,min(flow,edge[i].cap-edge[i].flow)); edge[i].flow+=tmp; edge[i^1].flow-=tmp; cur[u]=i; if(tmp)return tmp; } } return 0; } bool modify_label(){ int d=INF; for(int u=0;u<N;u++) if(vis[u]) for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; if(edge[i].cap>edge[i].flow&&!vis[v]) d=min(d,dis[v]+edge[i].cost-dis[u]); } if(d==INF)return false; for(int i=0;i<N;i++) if(vis[i]){ vis[i]=false; dis[i]+=d; } return true; } /* 直接调用获取最小费用和最大流 输入:start-源点,end-汇点,n-点的总个数(编号从0开始) 返回值:pair<int,int>第一个是最小费用,第二个是最大流 */ pair<int,int> mincostmaxflow(int start,int end,int n){ ss=start,tt=end,N=n; min_cost=max_flow=0; for(int i=0;i<n;i++)dis[i]=0; while(1){ for(int i=0;i<n;i++)cur[i]=head[i]; while(1){ for(int i=0;i<n;i++)vis[i]=false; int tmp=aug(ss,INF); if(tmp==0)break; max_flow+=tmp; min_cost+=tmp*dis[ss]; } if(!modify_label())break; } return make_pair(min_cost,max_flow); } }solve; struct point{//图中的一个点 int x; int y; }; point man[128];//存储人 point house[128];//存储房子 int man_sum;//人的总数 int house_sum;//房子的总数 int main(){ int N,M;//N*M的矩阵 char str[128]; int S,T;//超级源点,超级汇点 //int mincost; //int maxflow; pair<int,int>pr;//最小花费,最大流 while(~scanf("%d%d",&N,&M)){ if(N==0&&M==0)break; man_sum=0; house_sum=0; for(int i=0;i<N;++i){ scanf("%s",str); for(int j=0;j<M;++j){ if(str[j]=='m'){ man[man_sum].x=i; man[man_sum++].y=j; } else if(str[j]=='H'){ house[house_sum].x=i; house[house_sum++].y=j; } } } solve.init(); for(int i=0;i<man_sum;++i){ for(int j=0;j<house_sum;++j){ solve.addedge(i,man_sum+j,1,abs(man[i].x-house[j].x)+abs(man[i].y-house[j].y)); } } //超级源点 S=man_sum+house_sum; for(int i=0;i<man_sum;++i){ solve.addedge(S,i,1,0); } //超级汇点 T=man_sum+house_sum+1; for(int i=0;i<house_sum;++i){ solve.addedge(man_sum+i,T,1,0); } pr=solve.mincostmaxflow(S,T,man_sum+house_sum+2); printf("%d\n",pr.first); } return 0; }
View Code
相关文章推荐
- hdu1058 Humble Numbers
- Lingo 做线性规划 - Asset allocation and Portfolio models
- 电脑翻墙登陆google
- GO语言标准库概览
- org.hibernate.proxy.HibernateProxy.Forgot to register a type adapter 解决方案
- SAP ABAP收货或者货物移动(MIGO,MB11,MB1A)在保存时候的增强点
- Gost hash的C源码
- TWaver家族新成员 — Legolas工业自动化设计平台
- nsq源码阅读笔记之nsqd(一)——nsqd的配置解析和初始化
- Golang实现带优先级的channel
- 【django】搭建博客教程(2)——Template的使用
- 2 kNN-K-Nearest Neighbors algorithm k邻近算法(二)
- Google Authenticator安全配置ssh二次验证登录
- begoo 的路由 详细
- OC_分类(Category)学习笔记
- LightOJ 1030 Discovering Gold
- Visual Studio Code + Golang1.5 debug + MAC OS X 10.11
- Google protobuf的安装及使用
- 安装GOOGLE-AUTHENTICATOR验证器
- Google七夕情人节Doodle背后技术揭秘