3171. [TJOI2013]循环格【费用流】
Description
,你可以沿着箭头防线在格子间行走。即如果(r,c)是一个左箭头,那么走到(r,c-1);如果是右箭头那么走到(r,c+1);如果是上箭头那么走到(r-1,c);如果是下箭头那么走到(r+1,c);每一行和每一列都是循环的,即如果走出边界,你会出现在另一侧。
一个完美的循环格是这样定义的:对于任意一个起始位置,你都可以i沿着箭头最终回到起始位置。如果一个循环格不满足完美,你可以随意修改任意一个元素的箭头直到完美。给定一个循环格,你需要计算最少需要修改多少个元素使其完美。
Input
第一行两个整数R,C。表示行和列,接下来R行,每行C个字符LRUD,表示左右上下。
Output
一个整数,表示最少需要修改多少个元素使得给定的循环格完美
Sample Input
RRRD
URLL
LRRR
Sample Output
HINT
1<=R,L<=15
原题题意即为将图转化成每个点入度出度恰好为1
拆点,拆成入点和出点
向本来指向的边连费用为0的边
向周围的边连费用为1的边
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#define id(x,y) (x-1)*m+y
#define N (10000+10)
#define M (1000000+10)
using namespace std;
bool used[N];
int n,m,s,e,z,Ans,a[][];
int num_edge,head[N];
int dis[N],INF,pre[N];
int dx[]= {,-,,,},dy[]= {,,,-,};
char st[];
queue<int>q;
struct node
{
int to,next,Flow,Cost;
} edge[M*]; void add(int u,int v,int l,int c)
{
edge[++num_edge].to=v;
edge[num_edge].next=head[u];
edge[num_edge].Flow=l;
edge[num_edge].Cost=c;
head[u]=num_edge;
} bool Spfa(int s,int e)
{
memset(dis,0x7f,sizeof(dis));
memset(pre,-,sizeof(pre));
dis[s]=;
used[s]=true;
q.push(s);
while (!q.empty())
{
int x=q.front();
q.pop();
for (int i=head[x]; i!=; i=edge[i].next)
if (dis[x]+edge[i].Cost<dis[edge[i].to] && edge[i].Flow>)
{
dis[edge[i].to]=dis[x]+edge[i].Cost;
pre[edge[i].to]=i;
if (!used[edge[i].to])
{
used[edge[i].to]=true;
q.push(edge[i].to);
}
}
used[x]=false;
}
return dis[e]!=INF;
} int MCMF(int s,int e)
{
int Fee=;
while (Spfa(s,e))
{
int d=INF;
for (int i=e; i!=s; i=edge[((pre[i]-)^)+].to)
d=min(d,edge[pre[i]].Flow);
for (int i=e; i!=s; i=edge[((pre[i]-)^)+].to)
{
edge[pre[i]].Flow-=d;
edge[((pre[i]-)^)+].Flow+=d;
}
Fee+=d*dis[e];
}
return Fee;
} int main()
{
memset(&INF,0x7f,sizeof(INF));
s=,e=;
scanf("%d%d",&n,&m);
for (int i=; i<=n; ++i)
{
scanf("%s",st);
for (int j=; j<=m; ++j)
{
if (st[j-]=='U') a[i][j]=;
if (st[j-]=='D') a[i][j]=;
if (st[j-]=='L') a[i][j]=;
if (st[j-]=='R') a[i][j]=;
add(s,id(i,j),,);
add(id(i,j),s,,);
add(id(i,j)+m*n,e,,);
add(e,id(i,j)+m*n,,);
}
}
for (int i=; i<=n; ++i)
for (int j=; j<=m; ++j)
for (int k=; k<=; ++k)
{
int x=i+dx[k],y=j+dy[k];
if (x<) x=n;
if (x>n) x=;
if (y<) y=m;
if (y>m) y=;
add(id(i,j),id(x,y)+m*n,,(k!=a[i][j]));
add(id(x,y)+m*n,id(i,j),,-(k!=a[i][j]));
}
printf("%d",MCMF(s,e));
}
3171. [TJOI2013]循环格【费用流】的更多相关文章
- Bzoj 3171: [Tjoi2013]循环格 费用流
3171: [Tjoi2013]循环格 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 741 Solved: 463[Submit][Status][ ...
- [TJOI2013]循环格 费用流 BZOJ3171
题目背景 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位(r,c),你可以沿着箭头方向在格子间行走.即:如果 ...
- BZOJ 3171 [Tjoi2013]循环格(费用流)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3171 [题目大意] 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子. 每 ...
- BZOJ 3171 循环格(费用流)
题意 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位置(r,c),你可以沿着箭头防线在格子间行走.即如果(r ...
- bzoj 3171: [Tjoi2013]循环格
#include<cstdio> #include<iostream> #include<cstring> #define M 10000 #define inf ...
- bzoj 3171: [Tjoi2013]循环格 最小费用最大流
题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3171 题解: 首先我们很容易发现一个结论: 出现完美循环当且仅当所有点的出入度均为1 所 ...
- bzoj 3171 [Tjoi2013]循环格(MCMF)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3171 [题意] 给定一个方向矩阵,要求改变最少的格子,使得任意一个点都在一个环中. [ ...
- BZOJ_3171_[Tjoi2013]循环格_最小费用最大流
BZOJ_3171_[Tjoi2013]循环格_最小费用最大流 Description 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为 ...
- [Tjoi2013]循环格
[Tjoi2013]循环格 2014年3月18日1,7500 Description Input 第一行两个整数R,C.表示行和列,接下来R行,每行C个字符LRUD,表示左右上下. Output 一个 ...
随机推荐
- MySQL---7、常用操作
1.表列的添加.修改和删除 2.视图 3.字符集和校对集 4.触发器相关知识
- groovy运算符
import java.util.regex.Matcher /** * Created by Jxy on 2018/12/20 10:29 * groovy运算符 */ /*class opera ...
- The configuration section 'system.serviceModel' cannot be read because it is missing a section decla
将Asp.Net 2.0的Web Site搭建在IIS7(7.5)上时,运行出现500.19错误, 错误提示为 The configuration section 'system.serviceMod ...
- PAT 1029. Median
尼玛,数组偶数个数的时候取中位数是取中间两者中的前者,还tmd一直再算平均,卧槽 #include <iostream> #include <cstdio> #include ...
- JavaScript访问对象的属性和方法
对象的属性和方法统称为对象的成员. 访问对象的属性 在JavaScript中,可以使用“ . ”和“ [ ] ”来访问对象的属性. 二者区别:“ . ”表示法一般作为静态对象使用时来存取属性.而“[ ...
- Mongodb安装详解及mongochef视图工具安装。
按照国际惯例我们先来介绍一下MongoDB. MongoDB是一个基于分布式文件存储的数据库,由c++语言编写,为WEB应用提供可扩展的高性能数据存储解决方案.MongoDB属于非关系数据库,也不能说 ...
- Eclipse 分屏显示同一个代码文件
描述: 今天在使用Eclipse开发的时候不知按错哪个键,出现编辑框分屏显示同一个代码,由于之前没有使用过这一功能,所以就去查了一下,原来是Eclipse的分屏功能. 快捷键: 方式一:Window ...
- SparseArray代替HashMap
相信大家都明白,手机软件的开发不同于PC软件的开发,因为手机性能相对有限,内存也有限,所谓“寸土寸金”,可能稍有不慎,就会导致性能的明显降低.Android为了方便开发者,特意在android.uti ...
- HW—词频统计
第一次个人作业——词频统计 第一次做这种大作业,明显感觉陌生,各种规范和技能也是第一次使用,希望自己好运. 目录:一.基本要求 二.需求分析及时间估计 三.实现思路及过程 四.测试用例.时间性能分析及 ...
- linux 命令行模式下,浏览网页方法
Ubuntu自带最新版的Gnome桌面,拥有大量的服务和桌面应用程序,让您仅通过一张安装光盘就可以体验到无比舒适的操作环境.下文介绍的在ubuntu下使用终端命令行上网的方法. 第一步,需要安装一个名 ...