
POJ - 2195 Going Home 费用流+BFS
q; memset(dis,0x3f,sizeof(dis)); memset(inque,0,sizeof(inque)); q.push(s); dis[s]=0; inque[s]=1; incf[s]=inf; while(q.size()){ int u=q.front();q.pop(); inque[u]=0; for(int i=head[u];~i;i=edge[i].next){ if(!edge[i].flow) continue; int v=edge[i].v; if(dis[v]>dis[u]+edge[i].w){ dis[v]=dis[u]+edge[i].w; incf[v]=min(incf[u],edge[i].flow); pre[v]=i; if(!inque[v]){ q.push(v); inque[v]=1; } } } } if(dis[t]==inf) return 0; return 1; } void MCMF(){ while(spfa()){ int x=t; maxflow+=incf[t]; mincost+=dis[t]*incf[t]; int i; while(x!=s){ i=pre[x]; edge[i].flow-=incf[t]; edge[i^1].flow+=incf[t]; x=edge[i^1].v; } } } //bfs建图 int dxy[][2]={ { 1,0},{ -1,0},{ 0,1},{ 0,-1}}; bool vis[maxn][maxn]; int dis_bfs[maxn][maxn]; inline bool ju(int x,int y){ if(x<1||x>n||y<1||y>m||vis[x][y]) return 0; return 1; } void find(int x,int y){ memset(vis,0,sizeof vis); queue >q; pair p; q.push(make_pair(x,y)); dis_bfs[x][y]=0; vis[x][y]=1; while(q.size()){ p=q.front(),q.pop(); //找到了房子,连边 if(gh[p.first][p.second]<0){ add(gh[x][y],-gh[p.first][p.second]+100,1,dis_bfs[p.first][p.second]); add(-gh[p.first][p.second]+100,gh[x][y],0,-dis_bfs[p.first][p.second]); } for(int i=0;i<4;i++){ int tx=p.first+dxy[i][0],ty=p.second+dxy[i][1]; if(ju(tx,ty)){ vis[tx][ty]=1; q.push(make_pair(tx,ty)); dis_bfs[tx][ty]=dis_bfs[p.first][p.second]+1; } } } } int main(){ while(scanf("%d%d",&n,&m)==2){ if(!n&&!m) break; s=201,t=202; init(); getchar(); int cnt1=1,cnt2=-1;//编号 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ char ch=getchar(); while(ch=='\n'||ch==' ') ch=getchar(); if(ch=='.') gh[i][j]=0; else if(ch=='m') gh[i][j]=cnt1++; else gh[i][j]=cnt2--; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(gh[i][j]>0) find(i,j); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(gh[i][j]>0){ //源点-人 add(s,gh[i][j],1,0); add(gh[i][j],s,0,0); } else if(gh[i][j]<0){ //房子-汇点 add(-gh[i][j]+100,t,1,0); add(t,-gh[i][j]+100,0,0); } MCMF(); printf("%d\n",mincost); } }
发布日期:2021-05-10 11:28:36
浏览次数:21
分类:精选文章
本文共 2879 字,大约阅读时间需要 9 分钟。
题目链接
题意
给出n*m网格,中间有多个小人和房子,小人走一步花1¥,要求所有小人都到家(人房无对应关系),求最小花费
思路
第一眼以为是最短路,但由于小人和房子无对应关系,也就是一个小人选择不同房子会影响别的小人,所以直接最短路肯定wa的。
因为每个小人都要回一个房子,在这个基础上求最小花费。所以可以套费用流,超级源点向小人连边权1,房子向汇点连边权1,那么再来建立小人-房子的关系,费用流跑出来是最大流条件下(人人有房住)下最小花费,就是答案了。
具体小人-房子的联系,就遍历全图,对每一个小人跑bfs就行了。
代码
#include#include #include #include
发表评论
最新留言
表示我来过!
[***.240.166.169]2025年04月02日 15时22分09秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
<s>
2021-05-10
常见错误
2021-05-10
Oracle
2021-05-10
序列化与反序列化
2021-05-10
如何使用linux系统自带的led驱动
2021-05-10
IP-Guard回收客户端加密授权,已经加密的文档如何解密
2021-05-10
第十一节 IO编程
2021-05-10
Linux系统调用过程
2021-05-10
stm32 uv5打开uv4工程错误
2021-05-10
mysql怎么终止一个事务_MySql 中游标,事务,终止存储过程方法总结
2021-05-10
最基础的urllib.request.urlopen()基本使用
2021-05-10
C# 异常
2021-05-10
strlen sizeof 快
2021-05-10
【Java-27】Java常见错误记录
2021-05-10
andriod 开发错误记录
2021-05-10
生成树协议(二)
2021-05-10
创建一个简单的SpingBoot项目,并且部署到linux上运行
2021-05-10
mysql8.0及以上在my.cnf设置sql_mode之后mysql无法启动
2021-05-10
C语言编译错误列表
2021-05-10
万倍币传说不再,价值回归
2021-05-10