这题也可以用km做,我写的代码km比费用流快很多。

最小费用流:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<stdlib.h>
#define INF 1000000000
using namespace std;
const int maxn = ;
struct Set
{
int x,y;
}mnum[*],hnum[*];
struct node
{
int to;
int v;
int flag;
int cost;
int next;
}edge[maxn*maxn/];
char map[][];
int n,m,cou1,cou2,index,head[maxn],s,t,pre[maxn],fpre[maxn],N,dis[maxn];
int Get(int i,int j)
{
return abs(mnum[i].x-hnum[j].x)+abs(mnum[i].y-hnum[j].y);
}
void add(int x,int y,int v,int cost)
{
edge[index].to=y;
edge[index].v=v;
edge[index].cost=cost;
edge[index].flag=index+;
edge[index].next=head[x];
head[x]=index++;
edge[index].to=x;
edge[index].v=;
edge[index].cost=-cost;
edge[index].flag=index-;
edge[index].next=head[y];
head[y]=index++;
}
void makemap()
{
int i,j;
cou1=cou2=;
for(i=;i<n;i++)
{
for(j=;j<m;j++)
{
if(map[i][j]=='m')
{
mnum[++cou1].x=i;
mnum[cou1].y=j;
}
else if(map[i][j]=='H')
{
hnum[++cou2].x=i;
hnum[cou2].y=j;
}
}
}
index=;
memset(head,-,sizeof(head));
N=cou1+cou2+;
s=;
t=cou1+cou2+;
for(i=;i<=cou1;i++)
add(s,i,,);
for(i=;i<=cou2;i++)
add(i+cou1,t,,);
for(i=;i<=cou1;i++)
{
for(j=;j<=cou2;j++)
{
add(i,j+cou1,,Get(i,j));
}
}
}
bool spfa(int s,int t)
{
int vis[maxn];
queue<int>q;
memset(pre,-,sizeof(pre));
memset(vis,,sizeof(vis));
int i;
for(i=;i<=N;i++)
dis[i]=INF;
vis[s]=;
dis[s]=;
pre[s]=;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=;
for(i=head[u];i!=-;i=edge[i].next)
{
if(edge[i].v&&dis[edge[i].to]>dis[u]+edge[i].cost)
{
dis[edge[i].to]=dis[u]+edge[i].cost;
if(!vis[edge[i].to])
{
vis[edge[i].to]=;
q.push(edge[i].to);
}
pre[edge[i].to]=u;
fpre[edge[i].to]=i;
}
}
}
if(dis[t]>=INF)return false;
return true;
}
int main()
{
int i,j;
while(~scanf("%d%d",&n,&m))
{
if(!n&&!m)break;
for(i=;i<n;i++)
scanf("%s",map[i]);
makemap();
int ans=;
while(spfa(s,t))
{
int minflow=INF;
for(i=t;i!=;i=pre[i])
{
if(minflow>edge[fpre[i]].v)
minflow=edge[fpre[i]].v;
}
ans+=minflow*dis[t];
for(i=t;i!=;i=pre[i])
{
edge[fpre[i]].v-=minflow;
edge[edge[fpre[i]].flag].v+=minflow;
}
}
printf("%d\n",ans);
}
}

km:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define INF 99999999
#define maxn 105
using namespace std;
struct node
{
int x;
int y;
}h[maxn],m[maxn];
char g[maxn][maxn];
int map[maxn][maxn],pr[maxn],pl[maxn],visr[maxn],visl[maxn],match[maxn],slack[maxn];
int col,row;
void init(int x)
{
int i,j;
for(i=;i<=x;i++)
for(j=;j<=x;j++)
if(i==j)map[i][j]=;
else map[i][j]=INF;
}
int dfs(int u,int n)
{
int i,j;
visl[u]=;
for(i=;i<n;i++)
{
if(!visr[i])
{
int val=pl[u]+pr[i]-map[u][i];
if(val==)
{
visr[i]=;
if(match[i]==-||dfs(match[i],n))
{
match[i]=u;
return ;
}
}
if(val>&&val<slack[i])
slack[i]=val;
}
}
return ;
}
int km(int n)
{
int i,j;
memset(pr,,sizeof(pr));
memset(match,-,sizeof(match));
for(i=;i<n;i++)
pl[i]=INF;
for(i=;i<n;i++)
{
for(j=;j<n;j++)
slack[j]=INF;
while()
{
memset(visr,,sizeof(visr));
memset(visl,,sizeof(visl));
if(dfs(i,n))break;
int k=INF;
for(j=;j<n;j++)
{
if(!visr[j]&&slack[j]<k)
k=slack[j];
}
for(j=;j<n;j++)
{
if(visl[j])
pl[j]-=k;
if(visr[j])
pr[j]+=k;
}
}
}
int res=;
for(i=;i<n;i++)
{
res+=map[match[i]][i];
}
return res;
}
int main()
{
int i,j;
while(scanf("%d%d",&row,&col)!=EOF)
{
if(row==&&col==)
break;
int count1=,count2=;
for(i=;i<row;i++)
scanf("%s",g[i]);
for(i=;i<row;i++)
for(j=;j<col;j++)
{
if(g[i][j]=='H')
{
h[count1].x=i;h[count1++].y=j;
}
else if(g[i][j]=='m')
{
m[count2].x=i;m[count2++].y=j;
}
}
init(count1);
for(i=;i<count1;i++)
for(j=;j<count2;j++)
{
map[i][j]=-(abs(h[i].x-m[j].x)+abs(h[i].y-m[j].y));
}
printf("%d\n",-km(count1));
}
}

poj2195&&hdu1533 最小费用流的更多相关文章

  1. poj-2195(最小费用流)

    题意:给你一个n*m的地图,H代表这个点有一个房子,m代表这个点是一个人,每次h走一步就花费一,问最小花费使得每个人能进入一个房间 代码:建立一个源点和汇点,每个人和源点相连,每个房子和汇点相连,每个 ...

  2. POJ2195&&HDU1533(KB11-D 最小费用最大流)

    Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 23515   Accepted: 11853 Desc ...

  3. POJ2195 最小费用流

    题目:http://poj.org/problem?id=2195 处理出每个人到每个门的曼哈顿距离,分别建立容量为1费用为曼哈顿距离的边,在源点和每个人人之间建立容量为1费用为0的边,在门和汇点之间 ...

  4. POJ2195 Going Home 【最小费用流】+【最佳匹配图二部】

    Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18169   Accepted: 9268 Descr ...

  5. POJ 2195Going Home(网络流之最小费用流)

    题目地址:id=2195">POJ2195 本人职业生涯费用流第一发!!快邀请赛了.决定还是多学点东西.起码碰到简单的网络流要A掉.以后最大流费用流最小割就一块刷. 曾经费用流在我心目 ...

  6. POJ 2195 Going Home 最小费用流

    POJ2195 裸的最小费用流,当然也可以用KM算法解决,但是比较难写. 注意反向边的距离为正向边的相反数(因此要用SPFA) #include<iostream> #include< ...

  7. POJ-2195(最小费用最大流+MCMF算法)

    Going Home POJ-2195 这题使用的是最小费用流的模板. 建模的时候我的方法出现错误,导致出现WA,根据网上的建图方法没错. 这里的建图方法是每次到相邻点的最大容量为INF,而花费为1, ...

  8. HDU 4067 hdoj 4067 Random Maze 最小费用流

    给出n个点,m条边,入口s和出口t,对于每条边有两个值a,b,如果保留这条边需要花费:否则,移除这条边需要花费b. 题目要求用最小费用构造一个有向图满足以下条件: 1.只有一个入口和出口 2.所有路都 ...

  9. POJ 2516:Minimum Cost(最小费用流)

    https://vjudge.net/problem/11079/origin 题意:有N个商店和M个供应商和K种物品,每个商店每种物品有一个需求数,每个供应商每种物品有一个供应量,供应商到商店之间的 ...

随机推荐

  1. iPhone X 底部菜单走光的问题

    刘海的问题.我们一直没有关注.客户反映没有自适应iphone X. 解决方法就是写个head里面添加meta新属性+伪类:after+media screen媒体查询相结合一下.解决问题.供大家参考一 ...

  2. psu online course

    https://onlinecourses.science.psu.edu/statprogram/programs Graduate Online Course Overviews Printer- ...

  3. 出现大量rcuob进程

    方法一: vim /etc/default/grub,在GRUB_CMDLINE_LINUX这一行末尾添加nr_cpus=2,然后执行命令grub2-mkconfig -o /boot/grub2/g ...

  4. Redis消息通知

    Redis的消息通知通过列表类型实现,分为两种模式:阻塞式.发布/订阅式: 阻塞式 顾名思义,消息生产者负责生产消息,并将消息放到队列的一端,消息的消费者负责消费消息,从队列的另一端取出消息,然后对其 ...

  5. HDFS应用实例

  6. Spring学习:程序的耦合和解耦的思路分析

    程序的耦合 耦合:程序间的依赖关系 包括: 类之间的依赖 方法间的依赖 解耦: 降低程序间的依赖关系 在实际开发中: 应该做到,编译期不依赖,运行时才依赖 解耦思路: 第一步:使用反射来创建对象,而避 ...

  7. H5C3--边框图片

    类似于android的.9图片,目的是为了防止图片因为内容的扩展而导致图片拉伸失真. <!DOCTYPE html> <html lang="en"> &l ...

  8. draft.js开发富文本编辑器

    写在前头的话 在react中去寻找一个好用的富文本编辑器网上很少有推荐的,搜到的也只有一些个人不成熟的作品,慢慢发现网上比较推荐的一个东东叫做draft.js. 这个东西在网上可以找到的教程也是手指头 ...

  9. python邮件发送:普通文本、html、添加附件

    # -*- coding: utf-8 -*- # @Time : 2019/9/19 13:46 # @Author : HuangWenjun # @Email : 350920551@qq.co ...

  10. JAVA Sftp 上传下载

    SftpUtils package xxx;import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com ...