POJ 2195 & HDU 1533 Going Home(最小费用最大流)
这就是一道最小费用最大流问题
最大流就体现到每一个‘m’都能找到一个‘H’,但是要在这个基础上面加一个费用,按照题意费用就是(横坐标之差的绝对值加上纵坐标之差的绝对值)
然后最小费用最大流模板就是再用最短路算法找最小费用路径。然后在找到这条路径上面的最大流。。就这样一直找下去
代码:
1 //这是一个最小费用最大流问题
2 //最大费用最小流只要在添加边的时候换一下位置就好了
3 //求最大费用最大流只需要把费用换成相反数,用最小费用最大流求解即可
4 #include <cstdio>
5 #include <cstring>
6 #include <algorithm>
7 #include <queue>
8 #include <cmath>
9 using namespace std;
10 const int MAXN = 10000;
11 const int MAXM = 100000;
12 const int INF = 0x3f3f3f3f;
13 struct Edge
14 {
15 int v, next, cap, flow, cost;
16 int x, y;
17 } e[MAXM];
18 struct shudui
19 {
20 int x,y;
21 }p1[MAXN],p2[MAXN];
22 int head[MAXN],tol;
23 int pre[MAXN],dis[MAXN];
24 bool vis[MAXN];
25 int N, M;
26 void init()
27 {
28 N = MAXN;
29 tol = 0;
30 memset(head, -1, sizeof(head));
31 }
32 void add_edge(int x,int y,int cap,int cost)
33 {
34 e[tol].v=y;
35 e[tol].cap=cap;
36 e[tol].flow=0;
37 e[tol].cost=cost;
38 e[tol].next=head[x];
39 head[x]=tol++;
40
41 e[tol].v=x;
42 e[tol].cap=0;
43 e[tol].flow=0;
44 e[tol].cost=-cost;
45 e[tol].next=head[y];
46 head[y]=tol++;
47 }
48 int spfa(int s,int t)
49 {
50 queue<int>r;
51 for(int i=0;i<MAXN;++i)
52 {
53 vis[i]=0;
54 dis[i]=INF;
55 pre[i]=-1;
56 }
57 dis[s]=0;
58 vis[s]=1;
59 r.push(s);
60 while(!r.empty())
61 {
62 //printf("**\n");
63 int u=r.front();
64 r.pop();
65 vis[u]=0;
66 for(int i=head[u];i!=-1;i=e[i].next)
67 {
68 int v=e[i].v;
69 if(e[i].cap>e[i].flow && dis[v]>dis[u]+e[i].cost)
70 {
71 dis[v]=dis[u]+e[i].cost;
72 pre[v]=i;
73 if(!vis[v])
74 {
75 vis[v]=1;
76 r.push(v);
77 }
78 }
79 }
80 }
81 if(pre[t]==-1) return 0;
82 else return 1;
83 }
84 int MincostMaxflow(int s,int t,int &cost)
85 {
86 int flow=0;
87 cost=0;
88 while(spfa(s,t))
89 {
90
91 int minn=INF;
92 for(int i=pre[t];i!=-1;i=pre[e[i^1].v])
93 {
94 if(minn>e[i].cap-e[i].flow)
95 {
96 minn=e[i].cap-e[i].flow;
97 }
98 }
99 for(int i=pre[t];i!=-1;i=pre[e[i^1].v])
100 {
101 e[i].flow+=minn;
102 e[i^1].flow-=minn;
103 cost+=e[i].cost*minn;
104 }
105 flow+=minn;
106 }
107 return flow;
108 }
109
110 int main()
111 {
112 int n,m,st,en;
113 char s[105][105];
114 while(~scanf("%d%d",&n,&m) && n+m)
115 {
116 init();
117 int index1=0,index2=0;
118 for(int i=1;i<=n;++i)
119 scanf("%s",s[i]+1);
120 st=0;
121 for(int i=1;i<=n;++i)
122 {
123 for(int j=1;j<=m;++j)
124 {
125 if(s[i][j]=='m')
126 {
127 index1++;
128 p1[index1].x=i;
129 p1[index1].y=j;
130
131 }
132 else if(s[i][j]=='H')
133 {
134 index2++;
135 p2[index2].x=i;
136 p2[index2].y=j;
137
138 }
139 }
140 }
141 //printf("%d %d\n",index1,index2);
142 en=index1+index2+1;
143 for(int i=1;i<=index1;++i)
144 {
145 add_edge(st,i,1,0);
146 }
147 for(int i=index1+1;i<=index1+index2;++i)
148 {
149 add_edge(i,en,1,0);
150 }
151 for(int i=1;i<=index1;++i)
152 {
153 for(int j=1;j<=index2;++j)
154 {
155 int cost=abs(p1[i].x-p2[j].x)+abs(p1[i].y-p2[j].y);
156 add_edge(i,index1+j,1,cost);
157 }
158 }
159 int ans=0;
160 MincostMaxflow(st,en,ans);
161 printf("%d\n",ans);
162 }
163 return 0;
164 }
POJ 2195 & HDU 1533 Going Home(最小费用最大流)的更多相关文章
- poj 2195 二分图带权匹配+最小费用最大流
题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目 ...
- POJ 2195:Going Home(最小费用最大流)
http://poj.org/problem?id=2195 题意:有一个地图里面有N个人和N个家,每走一格的花费是1,问让这N个人分别到这N个家的最小花费是多少. 思路:通过这个题目学了最小费用最大 ...
- hdu 1533 Going Home 最小费用最大流
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1533 On a grid map there are n little men and n house ...
- hdu 1533 Going Home 最小费用最大流 入门题
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- hdu 1533 Going Home 最小费用最大流 (模板题)
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- HDU 5988.Coding Contest 最小费用最大流
Coding Contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- hdu 3667(拆边+最小费用最大流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3667 思路:由于花费的计算方法是a*x*x,因此必须拆边,使得最小费用流模板可用,即变成a*x的形式. ...
- hdu 3488(KM算法||最小费用最大流)
Tour Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submis ...
- hdu 3395(KM算法||最小费用最大流(第二种超级巧妙))
Special Fish Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
随机推荐
- Python 日志打印之logging.getLogger源码分析
日志打印之logging.getLogger源码分析 By:授客 QQ:1033553122 #实践环境 WIN 10 Python 3.6.5 #函数说明 logging.getLogger(nam ...
- 【Java】Jsoup爬虫,一个简单获取京东商品信息的小Demo
简单记录 - Jsoup爬虫入门实战 数据问题?数据库获取,消息队列中获取中,都可以成为数据源,爬虫! 爬取数据:(获取请求返回的页面信息,筛选出我们想要的数据就可以了!) 我们经常需要分析HTML网 ...
- 【Oracle】如果有一个Oracle中的用户,想知道他有什么权限,怎么查看?
假如那到了一个新用户,test,想查看这test的所有权限都有哪些,可以这么操作 登录到test用户上,执行下面的SQL 1.查看test用户被赋予了哪些角色. select * from user_ ...
- RocketMQ在linx安装及其有关问题解决
Linx安装和使用: rocketmq官网:http://rocketmq.apache.org/ 首先安装JDK(推荐使用JDK1.8),并配置环境变量 下载rocketmq压碎包并解压到指定目录 ...
- 解决JS获取中文参数出现的乱码问题
在代码中增加如下js函数: function getUrlParam(name) { var reg = new RegExp("(^|&)" + name + " ...
- Linq.Expressions扩展ExpressionExtension
手上有一个以前项目用到的.NET工具类封装的DLL. 正好又想试一下动态LAMBDA表达式,用.NET Reflector看一下源码. public static class ExpressionEx ...
- Ubuntu安装记录
好吧,这成功地让我想起了那些边肯红薯边黑苹果的早晨······ 本人纯属Windows用腻,后期请大佬多多指教 前面因为没U盘而碰壁的内容在此不说,接下来因为太兴奋,关于安装U盘制作没记录什么.最终, ...
- vue原生文件上传,可以多文件上传
1.单文件上传 <template> <div> <label for="fileInput"> <i aria-hidden=" ...
- CentOS7,非LVM根分区扩容步骤:
1.查看现有的分区大小 非LVM分区,目前磁盘大小为40G,根分区总容量为40G,(是自定义分区安装的) 2.关机增加磁盘大小至100G 如果你们是vmwaer虚拟软件安装的那如下入扩容: 3.查看磁 ...
- git的使用学习笔记--项目版本操作
一.使用场景 版本回退:上线失败--需要回退到上个版本 二.操作 先编辑 vim text.txt git status git add . 这个命令能看到所有的增加操作 git com ...