这就是一道最小费用最大流问题

最大流就体现到每一个‘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(最小费用最大流)的更多相关文章

  1. poj 2195 二分图带权匹配+最小费用最大流

    题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目 ...

  2. POJ 2195:Going Home(最小费用最大流)

    http://poj.org/problem?id=2195 题意:有一个地图里面有N个人和N个家,每走一格的花费是1,问让这N个人分别到这N个家的最小花费是多少. 思路:通过这个题目学了最小费用最大 ...

  3. 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 ...

  4. hdu 1533 Going Home 最小费用最大流 入门题

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  5. hdu 1533 Going Home 最小费用最大流 (模板题)

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  6. HDU 5988.Coding Contest 最小费用最大流

    Coding Contest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  7. hdu 3667(拆边+最小费用最大流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3667 思路:由于花费的计算方法是a*x*x,因此必须拆边,使得最小费用流模板可用,即变成a*x的形式. ...

  8. hdu 3488(KM算法||最小费用最大流)

    Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  9. hdu 3395(KM算法||最小费用最大流(第二种超级巧妙))

    Special Fish Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

随机推荐

  1. 根据业务摸索出的一个selenium代码模版(python)

    前言 总算入行上班几个月了,不得不说业务是真的不消停啊.. 本人工作上经常遇到一种场景:为甲方做自动化接口处理工具,登录需要短信验证码,, 嘛算是摸索出了一套selenium代码模板,主要解决如下痛点 ...

  2. 使用 C# 9 的records作为强类型ID - 路由和查询参数

    上一篇文章,我介绍了使用 C# 9 的record类型作为强类型id,非常简洁 public record ProductId(int Value); 但是在强类型id真正可用之前,还有一些问题需要解 ...

  3. Job for docker.service failed because start of the service was attempted too often. See "systemctl status docker.service" and "journalctl -xe" for details. To force a start use "systemctl reset-failed

    安装docker时,自己添加了国内的hub.docker.com镜像 [root@ce-docker ~]# systemctl restart docker 出现以下报错:Job for docke ...

  4. Java运算符概要与数学函数

    运算符概要 在Java中,使用算术运算符+,-,*,/表示加减乘除运算,当参与/的运算的两个操作数都是整数时,表示整数除法,否则,表示浮点除法.整数的求余操作(有时称为取模),用%表示,例如,15/2 ...

  5. 1.5V转5V的最少电路的芯片电路图

    PW5100满足1.5V转5V的很简洁芯片电路,同时达到了最少的元件即可组成DC-DC电路1.5V转5V的升压转换器系统. PW5100在1.5V转5V输出无负载时,输入效率电流极低,典型值10uA. ...

  6. C++中输出变量类型的方法

    C++中输出变量类型的方法 在c++中输出变量或者数据类型,使用typeid().name()的方法.如下例子: #include <iostream> #include <stri ...

  7. 从synchronized和lock区别入手聊聊java锁机制

    写这篇文章之前,我去百度了一下啥叫锁,百度百科上写道:置于可启闭的器物上,以钥匙或暗码开启.确实我们一般理解的锁就是门锁,密码锁,但是在计算机科学中,锁又是啥,说实话,这个问题我也思考了很久,也没法很 ...

  8. DHCP中继配置

    (三台都需要关闭防火墙 前两台需要安装dhcp ) 第一台linux(vmnet2)(192.168.1.1) vim /etc/sysconfig/network-scripts/ifcfg-ens ...

  9. Mybatis参数预编译

    Mybatis参数预编译 一.数据库预编译介绍 1.数据库SQL语句编译特性: 数据库接受到sql语句之后,需要词法和语义解析,优化sql语句,制定执行计划.这需要花费一些时间.但是很多情况,我们的一 ...

  10. Vue整合swiper报错Could not compile template .....swiper\dist\css\swiper.css解决办法

    问题描述 今天做一个前端项目,安装幻灯片插件vue-awesome-swiper后 运行npm run dev 后报错如下: `ERROR Could not compile template E:\ ...