题目链接:点击查看

题目大意:给出一个n*n的地图,其中:

  1. #:代表墙
  2. .:代表空格子
  3. 大写字母:代表骑士
  4. m:代表谷仓

现在要求每个谷仓都要至少被一个骑士保护,规定骑士保护某个谷仓的代价是骑士到达谷仓的最短路,现在问如何分配才能让花费最小

题目分析:模型抽象出来就是个最小费用最大流的模板题了,关键在于如何转换模型,费用流的建图比较简单,一开始就说一下吧:

  1. 源点->每个骑士,流量为每个骑士可以保护谷仓的数量,花费为0
  2. 每个骑士->每个可到达的谷仓,流量为1,花费为最短路
  3. 每个谷仓->汇点,流量为1,花费为0

现在问题转换为了预处理出每个骑士可到达的谷仓并求出其最短路,因为是在一个二维矩阵中,不难想到用bfs可以直接搞一下,扩展的时候顺便维护步数,因为骑士最多只有26个,枚举每个骑士,对每个骑士进行bfs建边就好了

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int b[4][2]={0,1,0,-1,1,0,-1,0};const int N=1e3+100;//点const int M=1e4+100;//边struct Edge
{int to,w,cost,next;
}edge[M];int n,k,m,st=N-1,ed=st-1,id[35][35],head[N],cnt;char maze[35][35];bool book[35][35];void addedge(int u,int v,int w,int cost)
{edge[cnt].to=v;edge[cnt].w=w;edge[cnt].cost=cost;edge[cnt].next=head[u];head[u]=cnt++;edge[cnt].to=u;edge[cnt].w=0;edge[cnt].cost=-cost;edge[cnt].next=head[v];head[v]=cnt++;
}int d[N],incf[N],pre[N];bool vis[N];bool spfa(int s,int t)
{memset(d,inf,sizeof(d));memset(vis,false,sizeof(vis));memset(pre,-1,sizeof(pre));queue<int>q;q.push(s);vis[s]=true;incf[s]=inf;d[s]=0;while(!q.empty()){int u=q.front();q.pop();vis[u]=false;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;int cost=edge[i].cost;if(!w)continue;if(d[v]>d[u]+cost){d[v]=d[u]+cost;pre[v]=i;incf[v]=min(incf[u],w);if(!vis[v]){vis[v]=true;q.push(v);}}}}return pre[t]!=-1;
}int update(int s,int t)
{int x=t;while(x!=s){int i=pre[x];edge[i].w-=incf[t];edge[i^1].w+=incf[t];x=edge[i^1].to;}return d[t]*incf[t];
}void init()
{memset(head,-1,sizeof(head));cnt=0;
}int solve(int st,int ed)
{int ans=0;while(spfa(st,ed))ans+=update(st,ed);return ans;
}struct Node
{int x,y,step;Node(int X,int Y,int STEP){x=X;y=Y;step=STEP;}
};void bfs(int x,int y,int pos)
{memset(book,false,sizeof(book));queue<Node>q;q.push(Node(x,y,0));book[x][y]=true;while(q.size()){Node cur=q.front();q.pop();if(maze[cur.x][cur.y]=='m')//如果到达了谷仓,直接建边addedge(pos,id[cur.x][cur.y]+k,1,cur.step);for(int i=0;i<4;i++){int xx=cur.x+b[i][0];int yy=cur.y+b[i][1];if(xx<=0||yy<=0||xx>n||yy>n)continue;if(book[xx][yy])continue;if(maze[xx][yy]=='#')continue;book[xx][yy]=true;q.push(Node(xx,yy,cur.step+1));}}
}void build()
{for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(isupper(maze[i][j]))//枚举每个骑士进行bfs建边bfs(i,j,maze[i][j]-'A'+1);
}int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);int w;cin>>w;int kase=0;while(w--){init();scanf("%d%d%d",&n,&k,&m);int tot=0;for(int i=1;i<=n;i++){scanf("%s",maze[i]+1);for(int j=1;j<=n;j++)if(maze[i][j]=='m')id[i][j]=++tot;//对每个谷仓编号}for(int i=1;i<=k;i++){int num;scanf("%d",&num);addedge(st,i,num,0);}for(int i=1;i<=m;i++)addedge(i+k,ed,1,0);build();printf("Case %d: %d\n",++kase,solve(st,ed));}return 0;
}

LightOJ - 1243 Guardian Knights(最小费用最大流+bfs)相关推荐

  1. LightOJ - 1404 Sending Secret Messages(最小费用最大流)

    题目链接:点击查看 题目大意:给出一张由n个点和m条边组成的无向带权图,并且每个单位的权值都附加着一个花费,现在要求从点1到点n传输大小为p的数据,最小需要多少花费 题目分析:最小费用最大流的模板题目 ...

  2. LightOJ - 1409 Rent a Car(最小费用最大流)

    题目链接:点击查看 题目大意:给出一家车辆展示公司,规定每辆新车只能展示一天,展示后可以选择去维护后才能继续展示,现在给出如下规则: 该公司需要连续展示n天汽车,每天需要展示的汽车数量为Ri 每天可以 ...

  3. 乌鲁木齐网络赛J题(最小费用最大流模板)

    ACM ICPC 乌鲁木齐网络赛 J. Our Journey of Dalian Ends 2017-09-09 17:24 243人阅读 评论(0) 收藏 举报  分类: 网络流(33)  版权声 ...

  4. POJ - 2516 Minimum Cost 最小费用最大流

    题目链接 题意:给n,m,k表示商店数,储存店数,种类数 然后给n*k表示每个水果店需求每种种类的数量: 表示成 need[i][j] 再给m*k表示每个储存店每种种类数量: 表示成store[i][ ...

  5. pku The Windy's KM最小权匹配 or 最小费用最大流

    http://poj.org/problem?id=3686 题意: 给定n个玩具,有m个车间,给出每个玩具在每个车间的加工所需的时间mat[i][j]表示第i个玩具在第j个车间加工所需的时间,规顶只 ...

  6. c语言最小费用流_策略算法工程师之路-图优化算法(一)(二分图amp;最小费用最大流)...

    目录 1.图的基本定义 2.双边匹配问题 2.1 二分图基本概念 2.2 二分图最大匹配求解 2.3 二分图最优匹配求解 2.4 二分图最优匹配建模实例 2.4.1 二分图最优匹配在师生匹配中的应用 ...

  7. 有源汇上下界最小费用可行流 ---- P4553 80人环游世界(拆点 + 有源汇上下界最小费用可行流)

    题目链接 题目大意: 解题思路: 又是一道裸题 . 首先它要求第iii个点只经过ViViVi那么我们就拆点ai,ai+na_i,a_{i+n}ai​,ai+n​一个点为入点,一个为出点这条边的流量范围 ...

  8. 有源汇上下界最小费用可行流 ---- P4043 [AHOI2014/JSOI2014]支线剧情(模板)

    题目链接 题目大意: 解题思路: 有源汇上下界最小费用可行流模板题目来着 先建出一个有源汇上下界可行流的图,然后注意建图的时候要把每条边的下界的费用提前加到ans里面 然后再对图跑费用流,就是补齐费用 ...

  9. Doctor NiGONiGO’s multi-core CPU(最小费用最大流模板)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=693 题意:有一个 k 核的处理器和 n 个工作,全部的工作都须要在一个核上处理一个单位的 ...

最新文章

  1. evolution ubuntu邮箱_Ubuntu下使用Evolution电子邮箱客户端
  2. ZooKeeper和Diamond有什么不同
  3. 重庆python培训-重庆Python培训班学完能做什么
  4. 二叉搜索树中第K小的元素
  5. PHP 学习 一 基础
  6. mvn tutorial
  7. 深入剖析ASP.NET的编译原理之二:预编译(Precompilation)
  8. adb 命令的个人记录
  9. python制作远程桌面控制_Python 远程桌面协议RDPY简介
  10. Android开发之注解式框架ButterKnife在ADT中的设置
  11. Google的wiki-map也上线了
  12. 自媒体人本质是互联网公司内容运营的角色
  13. 23种设计模式(十八)状态变化之备忘录
  14. 计算机科学论文生成器,数学论文生成器:从此一天一篇不再愁
  15. Flink实现异步IO实战
  16. Ubuntu vsftp搭建和C# Winform FTP操作
  17. c++模板函数的声明和定义该在什么文件里?
  18. 僵尸进程(zombie process)
  19. 如何使用aria2及webui-aria2下载百度云资源
  20. ContraD论文部分翻译与解读(Training GANs with Stronger Augmentations via Contrastive Discriminator)

热门文章

  1. python 字典程序_Python 字典(Dictionary)操作详解
  2. mysql 多数据库实例_Mysql多实例安装
  3. 理解吞吐量和停顿时间
  4. NIO和BIO如何影响应用程序的设计-API调用
  5. Semaphore源码分析
  6. 用户操作-用户详情查询流程分析
  7. 使用Properties集合存储数据,遍历取出Properties集合中的数据
  8. ExecutorService- Future - Java多线程编程
  9. Dubbo + Zookeeper入门初探
  10. Spring--IoC(2)