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 一个 ...
随机推荐
- java自学之路-开篇
开篇 想写一些java自学文章的心思起好久了,也在心里规划了一段时间,今天终于开始正式付于纸上.接下来要写的内容从java基础开始,一步步到正式工作用到的技术,整个体系适合java初学者自学.内容可能 ...
- bnu 被诅咒的代码
http://www.bnuoj.com/bnuoj/problem_show.php?pid=10792 被诅咒的代码 Time Limit: 1000ms Memory Limit: 65536K ...
- csharp: using wininet.dll
/// <summary> /// Windows Embedded CE 6.0 R3 WinInet Functions /// https://technet.microsoft.c ...
- Django中用Jquery实现不刷新页面进行身份验证和计算器功能
1.下载jquery http://www.jq22.com/jquery-info122 下载解压之后加入工程中的static文件夹中 2.路由分发. """Djang ...
- Maven学习总结(七):Maven的聚合和继承
一.聚合 如果我们想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合 1.1.聚合配置代码 1 <modules> 2 <module>模块一</module&g ...
- mybatis三种传值方式
第一种:按序列传参(dao层的函数方法)[sql] Public User selectUser(String name,String area); 对应的Mapper.xml [sql] <s ...
- AE+C#实现:在SceneControl里打开和保存
来自:http://www.cnblogs.com/zhuxy/archive/2012/03/30/2424672.html 之前编写这段代码,发现一直没有C#编写的,现在贴出来,希望对大家有用 此 ...
- LintCode2016年8月22日算法比赛----平面列表
平面列表 题目描述 给定一个列表,该列表中的每个要素要么是个列表,要么是整数.将其变成一个只包含整数的简单列表. 注意事项 如果给定的列表中的要素本身也是一个列表,那么它也可以包含列表. 样例 给定 ...
- linux 查看在线服务进程
输入命令:netstat -ltunp 注意,这个-与l之间是没有空格的 要对进程进行监测和控制,首先必须要了解当前进程的情况,也就是需要查看当前进程, 而ps命令(Process Status)就 ...
- 在SQL service或Oracle中将数字转换成有千位符号
1.在SQL service中的写法: --Function主体 CREATE FUNCTION [dbo].[FnMoneyStyle](@Number )) RETURNS VARCHAR() A ...