hdu 1533 KM或费用流
以前用KM写过,现在再用费用流写。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <utility>
#define abs(a) ((a)<0?-(a):(a))
#define maxn 210
#define oo 0x3f3f3f3f
using namespace std; struct Edge {
int u, v, c, f;
Edge( int u, int v, int c, int f ):u(u),v(v),c(c),f(f){}
};
struct Mcmf {
int n, src, dst;
vector<Edge> edge;
vector<int> g[maxn];
int dis[maxn], pth[maxn], ext[maxn]; void init( int n, int src, int dst ) {
this->n = n;
this->src = src;
this->dst = dst;
for( int i=; i<=n; i++ )
g[i].clear();
edge.clear();
}
void add_edge( int u, int v, int c, int f ) {
g[u].push_back( edge.size() );
edge.push_back( Edge(u,v,c,f) );
g[v].push_back( edge.size() );
edge.push_back( Edge(v,u,-c,) );
}
bool spfa( int &flow, int &cost ) {
queue<int> qu;
memset( dis, 0x3f, sizeof(dis) );
qu.push( src );
ext[src] = true;
dis[src] = ;
pth[src] = -;
while( !qu.empty() ) {
int u=qu.front();
qu.pop();
ext[u] = false;
for( int t=; t<g[u].size(); t++ ) {
Edge &e = edge[g[u][t]];
if( e.f && dis[e.v]>dis[e.u]+e.c ) {
dis[e.v] = dis[e.u]+e.c;
pth[e.v] = g[u][t];
if( !ext[e.v] ) {
ext[e.v] = true;
qu.push( e.v );
}
}
}
}
if( dis[dst]==oo ) return false;
int flw = oo;
for( int eid=pth[dst]; eid!=-; eid=pth[edge[eid].u] )
flw = min( flw, edge[eid].f );
for( int eid=pth[dst]; eid!=-; eid=pth[edge[eid].u] ) {
edge[eid].f -= flw;
edge[eid^].f += flw;
}
flow += flw;
cost += flw*dis[dst];
return true;
}
void mcmf( int &flow, int &cost ) {
flow = cost = ;
while( spfa(flow,cost) );
}
}; int n, m;
int aa[maxn][], bb[maxn][], ta, tb;
Mcmf M; int main() {
ios::sync_with_stdio( false );
while() {
cin>>n>>m;
if( n== && m== ) return ;
ta = tb = ;
for( int i=; i<=n; i++ )
for( int j=; j<=m; j++ ) {
char ch;
cin>>ch;
if( ch=='m' ) {
ta++;
aa[ta][] = i;
aa[ta][] = j;
} else if( ch=='H' ) {
tb++;
bb[tb][] = i;
bb[tb][] = j;
}
}
M.init( ta+tb+, ta+tb+, ta+tb+ );
for( int i=; i<=ta; i++ )
M.add_edge( M.src, i, , );
for( int j=ta+; j<=ta+tb; j++ )
M.add_edge( j, M.dst, , );
for( int i=; i<=ta; i++ )
for( int j=ta+; j<=ta+tb; j++ ) {
int dis = abs(aa[i][]-bb[j-ta][])+abs(aa[i][]-bb[j-ta][]);
M.add_edge( i, j, dis, );
}
int flow, cost;
M.mcmf( flow, cost );
cout<<cost<<endl;
}
}
hdu 1533 KM或费用流的更多相关文章
- HDU 3488--Tour(KM or 费用流)
因为每个点只能经过一次 所以考虑拆点 这题有坑,有重边.. KM算法 把一个点拆成入点和出点 入点在X部,出点在Y步. 如果u,v之间有路径,就在X部的u点连接Y部的v点 求完美匹配. 当完美匹配的时 ...
- POJ 2195 Going Home / HDU 1533(最小费用最大流模板)
题目大意: 有一个最大是100 * 100 的网格图,上面有 s 个 房子和人,人每移动一个格子花费1的代价,求最小代价让所有的人都进入一个房子.每个房子只能进入一个人. 算法讨论: 注意是KM 和 ...
- HDU 5988 Coding Contest(费用流+浮点数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5988 题目大意: 给定n个点,m条有向边,每个点是一个吃饭的地方,每个人一盒饭.每个点有S个人,有B盒 ...
- POJ 2135 Farm Tour && HDU 2686 Matrix && HDU 3376 Matrix Again 费用流求来回最短路
累了就要写题解,近期总是被虐到没脾气. 来回最短路问题貌似也能够用DP来搞.只是拿费用流还是非常方便的. 能够转化成求满流为2 的最小花费.一般做法为拆点,对于 i 拆为2*i 和 2*i+1.然后连 ...
- Going Home HDU - 1533(最大费用最小流)
On a grid map there are n little men and n houses. In each unit time, every little man can move one ...
- HDU 1533 KM算法(权值最小的最佳匹配)
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- HDU 3315 My Brute(费用流)
职务地址:HDU 3315 这个题的思路全然是自己想出来的,自我感觉挺巧妙的. . .(大牛勿喷.. . )对大胆建图又多了一份信心. 详细思路是构造一个二分图,Si连源点.Xi连汇点,流量都是1,费 ...
- HDU 2686 Matrix(最大费用流)
Matrix Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- HDU 1533 & KM模板
题意 求二分图最小完备匹配. SOL 建个图那么方便的事情是吧...然后边权都是正的(好像根边权也没什么关系),既然要求最小那么把边权取个相反数跑个KM就好了.. CODE: /*========== ...
随机推荐
- Linux下使用tree命令查看目录结构
Linux下的文件虽然是层次型组织结构的,但是我们平时登录到主机上的时候都是使用的各种shell并没有图形界面,看上去很不直观,Linux下有个小命令叫做tree,可以以目录树的形式显示文件结构,类似 ...
- typeof运算符
javascript中typeof用来判断一个变量或表达式的数据类型. typeof 返回值有六种可能: "number," "string," "b ...
- Go语言 2 变量、常量和数据类型
文章由作者马志国在博客园的原创,若转载请于明显处标记出处:http://www.cnblogs.com/mazg/ Go学习群:415660935 2.1 变量 变量是对一块内存空间的命名,程序可以通 ...
- 遍历目录大小——php经典实例
遍历目录大小——php经典实例 <?php function dirSize($dir){ //定义大小初始值 $sum=; //打开 $dd=opendir($dir); //遍历 while ...
- Android 开发笔记(二)菜单设计
菜单设计一 // 创建菜单 public boolean onCreateOptionsMenu(Menu menu) { menu.add(0, 0, 0, "关于"); men ...
- Linux下通过源码编译安装程序(configure/make/make install的作用,然后在/etc/profile文件里修改PATH环境变量)
一.程序的组成部分 Linux下程序大都是由以下几部分组成: 二进制文件:也就是可以运行的程序文件 库文件:就是通常我们见到的lib目录下的文件 配置文件:这个不必多说,都知道 帮助文档:通常是我们在 ...
- python多线程下载文件
从文件中读取图片url和名称,将url中的文件下载下来.文件中每一行包含一个url和文件名,用制表符隔开. 1.使用requests请求url并下载文件 def download(img_url, i ...
- SwitchSharp代理插件的安装和使用
参考链接: http://bbs.feng.com/read-htm-tid-8227283.html 安装参考链接: http://jingyan.baidu.com/article/380abd0 ...
- java版云笔记(一)
云笔记项目 这个项目的sql文件,需求文档,需要的html文件,jar包都可以去下载,下载地址为:http://download.csdn.net/download/liveor_die/998584 ...
- Crypt加密函数简介(C语言)
定义函数 char * crypt (const char *key,const char * salt); 函数说明 crypt是个密码加密函数,它是基于Data Encryption Standa ...