poj2195 Going Home(最大费用最小流)
2016-07-22 20:12
459 查看
题目链接:
http://poj.org/problem?id=2195
求最大流最小费用。主要是加边,
先从源点到各个人m,费用为0流量为1,。
然后从m到H,费用为距离,流量为1.
最后从H到汇点,费用为0,流量为1.
代码:
http://poj.org/problem?id=2195
求最大流最小费用。主要是加边,
先从源点到各个人m,费用为0流量为1,。
然后从m到H,费用为距离,流量为1.
最后从H到汇点,费用为0,流量为1.
代码:
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<stdlib.h> #define inf 0x3f3f3f3f #define MM 10005 #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; struct Edge{ int from,to,cap,flow,cost,next; Edge(){} Edge(int from,int to,int cap,int flow,int cost,int next){ this->from=from; this->to=to; this->cap=cap; this->flow=flow; this->cost=cost; this->next=next; } }ed[666666]; char str[105][105]; int n,m,s,t,head,tail,lnum; int vis[MM],dis[MM],pre[MM];//pre 上一条弧 int cag[MM],que[MM*3],start[MM];//cag 可改进量 pair<int,int>house[MM],people[MM]; void init(){ lnum=0; rep(i,s,t) start[i]=-1; } void add(int x,int y,int v,int c){ ed[lnum]=Edge(x,y,v,0,c,start[x]); start[x]=lnum++; ed[lnum]=Edge(y,x,0,0,-c,start[y]); start[y]=lnum++; } bool spfa(int& flow,int& cost){ rep(i,s,t) dis[i]=inf,vis[i]=0; head=tail=0; dis[s]=0;vis[s]=1;pre[s]=0;cag[s]=inf; que[tail++]=s; while(head<tail){ int x=que[head++]; vis[x]=0; for(int i=start[x];~i;i=ed[i].next){ Edge& e=ed[i]; if(e.cap>e.flow&&dis[e.to]>dis[x]+e.cost){ dis[e.to]=dis[x]+e.cost; pre[e.to]=i; cag[e.to]=min(cag[x],e.cap-e.flow); if(!vis[e.to]){ que[tail++]=e.to; vis[e.to]=1; } } } } if(dis[t]==inf) return false; flow+=cag[t]; cost+=dis[t]*cag[t]; int x=t; while(x!=s){ ed[pre[x]].flow+=cag[t]; ed[pre[x]^1].flow-=cag[t]; x=ed[pre[x]].from; } return true; } int Mincost(){ int flow=0,cost=0; while((spfa(flow,cost))); return cost; } int main() { int i,j,k,tt1,tt2; while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0)break; init(); tt1=tt2=0; for(i=1;i<=n;i++) for(j=1;j<=m;j++){ cin>>str[i][j]; if(str[i][j]=='m'){ people[++tt1]=make_pair(i,j); } if(str[i][j]=='H'){ house[++tt2]=make_pair(i,j); } } s=0;t=tt1+tt2+1; for(i=1;i<=tt1;i++){ add(0,i,1,0); } for(i=1;i<=tt1;i++) for(j=1;j<=tt2;j++){ int d=abs(people[i].first-house[j].first)+abs(people[i].second-house[j].second); add(i,tt1+j,1,d); } for(i=1;i<=tt2;i++){ add(tt1+i,t,1,0); } int ans = Mincost(); printf("%d\n",ans); } }
相关文章推荐
- google地图、高德地图基于基站定位位置纠偏
- 类别(Category)与扩展(Extension)的区分
- 各个屏幕的logo尺寸要求
- golang基于websocket实现的简易聊天室程序
- Django入门:模板
- UVa 11090 Going in Cycle! BellmanFord 判负权环
- comments 在djiano 高版本问题
- golang使用sort接口实现排序示例
- Multiple dex files define Lcom/google/zxing/BarcodeFormat
- golang守护进程用法示例
- Ubuntu16.04虚拟机使用备注笔记
- Django的使用
- Golang1.7使用ICMP协议实现ping功能,带TIME和TTL
- golang模板template自定义函数用法示例
- Google VR Demo无法使用cocoapods更新的解决方法
- Golang的安装
- Welcome to buy 80% off cheapest rs 07 gold on RSorder 7.25 for Hidey holes
- CEF中文教程(google chrome浏览器控件) -- Windows下编译Chromium
- Google 编码风格之命名规范(备忘)
- Google 编码风格之命名规范(备忘)