Description

一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子。每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0)。给定一个起始位置(r,c)

,你可以沿着箭头防线在格子间行走。即如果(r,c)是一个左箭头,那么走到(r,c-1);如果是右箭头那么走到(r,c+1);如果是上箭头那么走到(r-1,c);如果是下箭头那么走到(r+1,c);每一行和每一列都是循环的,即如果走出边界,你会出现在另一侧。
一个完美的循环格是这样定义的:对于任意一个起始位置,你都可以i沿着箭头最终回到起始位置。如果一个循环格不满足完美,你可以随意修改任意一个元素的箭头直到完美。给定一个循环格,你需要计算最少需要修改多少个元素使其完美。

Input

第一行两个整数R,C。表示行和列,接下来R行,每行C个字符LRUD,表示左右上下。

Output

一个整数,表示最少需要修改多少个元素使得给定的循环格完美

Sample Input

3 4
RRRD
URLL
LRRR

Sample Output

2

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]循环格【费用流】的更多相关文章

  1. Bzoj 3171: [Tjoi2013]循环格 费用流

    3171: [Tjoi2013]循环格 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 741  Solved: 463[Submit][Status][ ...

  2. [TJOI2013]循环格 费用流 BZOJ3171

    题目背景 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位(r,c),你可以沿着箭头方向在格子间行走.即:如果 ...

  3. BZOJ 3171 [Tjoi2013]循环格(费用流)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3171 [题目大意] 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子. 每 ...

  4. BZOJ 3171 循环格(费用流)

    题意 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位置(r,c),你可以沿着箭头防线在格子间行走.即如果(r ...

  5. bzoj 3171: [Tjoi2013]循环格

    #include<cstdio> #include<iostream> #include<cstring> #define M 10000 #define inf ...

  6. bzoj 3171: [Tjoi2013]循环格 最小费用最大流

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3171 题解: 首先我们很容易发现一个结论: 出现完美循环当且仅当所有点的出入度均为1 所 ...

  7. bzoj 3171 [Tjoi2013]循环格(MCMF)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3171 [题意] 给定一个方向矩阵,要求改变最少的格子,使得任意一个点都在一个环中. [ ...

  8. BZOJ_3171_[Tjoi2013]循环格_最小费用最大流

    BZOJ_3171_[Tjoi2013]循环格_最小费用最大流 Description 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为 ...

  9. [Tjoi2013]循环格

    [Tjoi2013]循环格 2014年3月18日1,7500 Description Input 第一行两个整数R,C.表示行和列,接下来R行,每行C个字符LRUD,表示左右上下. Output 一个 ...

随机推荐

  1. IoC容器之Unity

    关于IoC.Unity见博友文章点击这里. 话不多说,上程序HelloUnity,程序采用VS2010,Unity2.1. 1.程序框架如下 2.类库HelloUnity.Objects,主要为实体类 ...

  2. java中equal和==的比较

    equals 方法是 java.lang.Object 类的方法. 有两种用法说明: (1)对于字符串变量来说,使用“==”和“equals()”方法比较字符串时,其比较方法不同. “==”比较两个变 ...

  3. 十、spark graphx的scala示例

    简介 spark graphx官网:http://spark.apache.org/docs/latest/graphx-programming-guide.html#overview spark g ...

  4. 撩课-Java每天5道面试题第26天

    161.简述一下springMVC当中的视图解析器 请求处理方法执行完成后,最终返回一个 ModelAndView 对象 对于那些返回 String,View 或 ModeMap 等类型的处理方法 S ...

  5. 撩课-Python-每天5道面试题-第2天

    一. 简述编程过程中, 注释的作用? (1) 方便开发人员自己理清楚代码思路 因为开发人员在拿到一个需求时, 首先应该思考的是如何将需求问题, 分解成具体的实施步骤; 第一步干啥, 第二步干啥, 第三 ...

  6. 代码实现SpringMvc

    偶然看到一篇100多行实现SpringMvc的博客,阅读后整理加实现出来.大家共勉!(纸上得来终觉浅,绝知此事要躬行.) 实现Spring的部分. Bean工厂,统一创建Bean: IOC,实现Bea ...

  7. I/O概述

    同步:同步等待,按照顺序执行,单线程.异步:异步并发,多线程. 阻塞:请求一个操作,如果条件不满足,一直等待需要的条件,直到条件满足.非阻塞:请求一个操作,如果条件不满足,则返回不满足条件的标志信息. ...

  8. Java 并发:Executor

    异常捕获 以前使用executor的时候,为了记录任务线程的异常退出会使用ThreadFactory来设置线程的UncaughtExceptionHandler,但是按照书上的验证发现,采用execu ...

  9. python学习之老男孩python全栈第九期_day027知识点总结——反射、类的内置方法

    一. 反射 ''' # isinstance class A:pass class B(A):pass a = A() print(isinstance(a,A)) # 判断对象和类的关系 print ...

  10. bootstrap学习笔记(网页开发小知识)

    这是我在学习Boostrap网页开发时遇到的主要知识点: 1.导航条navbar 添加.navbar-fixed-top类可以让导航条固定在顶部,固定的导航条会遮住页面上的其他内容,除非给<bo ...