【bzoj3171】[Tjoi2013]循环格
题目描述:
一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子。每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0)。给定一个起始位置(r,c)
,你可以沿着箭头防线在格子间行走。即如果(r,c)是一个左箭头,那么走到(r,c-1);如果是右箭头那么走到(r,c+1);如果是上箭头那么走到(r-1,c);如果是下箭头那么走到(r+1,c);每一行和每一列都是循环的,即如果走出边界,你会出现在另一侧。
一个完美的循环格是这样定义的:对于任意一个起始位置,你都可以i沿着箭头最终回到起始位置。如果一个循环格不满足完美,你可以随意修改任意一个元素的箭头直到完美。给定一个循环格,你需要计算最少需要修改多少个元素使其完美。
输入:
第一行两个整数R,C。表示行和列,接下来R行,每行C个字符LRUD,表示左右上下。
输出:
一个整数,表示最少需要修改多少个元素使得给定的循环格完美
样例输入:
3 4
RRRD
URLL
LRRR
样例输出:
2
题解:
这题有两种构图方法。首先,两种方法根据出入度都为1来构图。
第一种:
(1)将所有的点拆成两个点,将一个点连向源点S,另一个点连向汇点T,连的边都是容量为1,费用为0的。代表了每个点的出入度都是1 。
(2)一个点向四周的另一类点连出一条容量为1费用为0或1(如果无需修改就是0,否则需要修改就是1)的边。
(3)跑最小费用最大流
第二种:
(1)拆点同上,但连的边的容量为该点原本的入(出)度。
(2)对于每个方格(i, j),我们假设原本连的点为(x,y),那么把这个连向的点的第二类点向其他三个没连的点的第一类点连边,容量为1,费用为1。每个第一类点和第二类点之间都连一条容量为1,费用为0的边。
(3)同第一种
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#ifdef CT
#define debug(...) printf(__VA_ARGS__)
#define setfile()
#else
#define debug(...)
#define filename ""
#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif
#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
R char ch; R int cnt = 0; R bool minus = 0;
while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
ch == '-' ? minus = 1 : cnt = ch - '0';
while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
return minus ? -cnt : cnt;
}
#define maxn 20
#define maxcnt 1010
#define maxm 100010
struct Edge
{
int from, to, w, c;
Edge *next, *rev;
}*last[maxcnt], *prev[maxcnt], e[maxm], *ecnt = e;
int opt[maxn][maxn], id[maxn][maxn], s, t, ans;
int dis[maxcnt];
bool vis[maxcnt];
const int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
#define cmod(_a, _b) ((_a) % (_b) == 0 ? (_b) : (_a) % (_b))
inline void link(R int _a, R int _b, R int _w, R int _c)
{
*++ecnt = (Edge) {_a, _b, _w, _c, last[_a], ecnt + 1}; last[_a] = ecnt;
*++ecnt = (Edge) {_b, _a, 0, -_c, last[_b], ecnt - 1}; last[_b] = ecnt;
}
#define INF 23333333
std::queue <int> q;
inline bool spfa()
{
for (R int i = 0; i <= t; ++i) dis[i] = INF;
dis[s] = 0; vis[s] = 1; q.push(s);
while (!q.empty())
{
R int now = q.front(); q.pop();
for (R Edge *iter = last[now]; iter; iter = iter -> next)
{
if (iter -> w && iter -> c + dis[now] < dis[iter -> to])
{
dis[iter -> to] = iter -> c + dis[now];
prev[iter -> to] = iter;
if (!vis[iter -> to])
{
vis[iter -> to] = 1;
q.push(iter -> to);
}
}
}
vis[now] = 0;
}
return dis[t] != INF;
}
inline void mcmf()
{
R int x = INF;
for (R Edge *iter = prev[t]; iter; iter = prev[iter -> from])
cmin(x, iter -> w);
for (R Edge *iter = prev[t]; iter; iter = prev[iter -> from])
{
ans += x * iter -> c;
iter -> w -= x;
iter -> rev -> w += x;
}
}
int main()
{
R int n = FastIn(), m = FastIn(), cnt = 0;
for (R int i = 1; i <= n; ++i)
for (R int j = 1; j <= m; ++j)
{
id[i][j] = ++cnt;
R char ch;
while (ch = getc(), ch < 'A' || ch > 'Z');
if (ch == 'U') opt[i][j] = 0;
if (ch == 'D') opt[i][j] = 1;
if (ch == 'L') opt[i][j] = 2;
if (ch == 'R') opt[i][j] = 3;
}
s = 0; t = cnt << 1 | 1;
for (R int i = 1; i <= n; ++i)
for (R int j = 1; j <= m; ++j)
{
link(s, id[i][j], 1, 0);
link(id[i][j] + cnt, t, 1, 0);
for (R int k = 0; k < 4; ++k)
{
R int nx = i + dx[k], ny = j + dy[k];
link(id[i][j], id[cmod(nx, n)][cmod(ny, m)] + cnt, 1, k == opt[i][j] ? 0 : 1);
}
}
while (spfa()) mcmf();
printf("%d\n",ans );
return 0;
}
【bzoj3171】[Tjoi2013]循环格的更多相关文章
- BZOJ3171 Tjoi2013 循环格
传送门 Description 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位置(r,c) ,你可以沿着箭头 ...
- bzoj3171: [Tjoi2013]循环格(费用流)
传送门 其实这题的建图并不难(虽然我并没有想出来) 首先,每一个点的入度和出度必须为$1$ 那么我们考虑拆点 每个点的出度点向它能到达的点的入度点连边,容量$1$,如果方向为原来的方向则费用$0$否则 ...
- Bzoj 3171: [Tjoi2013]循环格 费用流
3171: [Tjoi2013]循环格 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 741 Solved: 463[Submit][Status][ ...
- [Tjoi2013]循环格
[Tjoi2013]循环格 2014年3月18日1,7500 Description Input 第一行两个整数R,C.表示行和列,接下来R行,每行C个字符LRUD,表示左右上下. Output 一个 ...
- 洛谷 P3965 [TJOI2013]循环格 解题报告
P3965 [TJOI2013]循环格 题目背景 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子. 每个元素有一个坐标(行,列),其中左上角元素坐标为\((0,0)\).给定一个起始位\ ...
- BZOJ_3171_[Tjoi2013]循环格_最小费用最大流
BZOJ_3171_[Tjoi2013]循环格_最小费用最大流 Description 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为 ...
- [TJOI2013]循环格 费用流 BZOJ3171
题目背景 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位(r,c),你可以沿着箭头方向在格子间行走.即:如果 ...
- 【BZOJ3171】[TJOI2013] 循环格(网络流)
点此看题面 大致题意: 给你一个循环格,每个格子有一个方向.问你至少修改多少格子,才能使从每个格子出发都能回到原格子. 建图 这是道网络流题目,主要就是考虑如何建图. 我们可以把每个点拆成两个点,一个 ...
- bzoj 3171: [Tjoi2013]循环格
#include<cstdio> #include<iostream> #include<cstring> #define M 10000 #define inf ...
随机推荐
- 伯努利分布、二项分布、多项分布、Beta分布、Dirichlet分布
1. 伯努利分布 伯努利分布(Bernoulli distribution)又名两点分布或0-1分布,介绍伯努利分布前首先需要引入伯努利试验(Bernoulli trial). 伯努利试验是只有两种可 ...
- 【Qt开发】V4L2 API详解 Camera详细设置
Camera的可设置项极多,V4L2 支持了不少.但Sam之前对这些设置的用法和涵义都是在看videodev2.h中边看边理解,感觉非常生涩.直到写这篇blog时,才发现v4l2有专门的SPEC来说明 ...
- How to attach multiple files in the Send Mail Task in SSIS
Let’s say you need to create a SSIS package that creates 2 files and emails the files to someone. Yo ...
- 题解 CF1140D 【Minimum Triangulation】
题意:求将一个n边形分解成(n-2)个三边形花费的最小精力,其中花费的精力是所有三角形的三顶点编号乘积的和(其中编号是按照顶点的顺时针顺序编写的) 考虑1,x,y连了一个三角形,x,y,z连了一个三角 ...
- navicat和Pycharm的连接
要安装好Mysql,并且实现了Mysql和Navicat的连接: 2.连接界面如下:点击连接,然后点击MySQL就可以看到如下界面 3. 然后就出现新建连接的设置,连接名自己起,用户名和密码和在MyS ...
- textarea标签输出内容时不能顶格(左对齐)输出
我用textarea输出文本内容的时候出现下面的问题:文本内容在action里测试没有问题(文本内容前面没有空格),但是在jsp页面textare标签中输出文本内容时,文本内容前面却出现一些多余的空格 ...
- Java——绘制五角星
Java2D支持通过GeneralPath实现绘制任意的几何形状. 步骤:1)实例化GeneralPath对象 2)调用moveTo()方法锚地开始点坐标 3)调用lineTo()或curveTo() ...
- java中的数据类型,基本数据类型及其包装类型
java中的8大基本类型及其包装类型 1,int--->Integer 2,byte--->Byte 3,short--->Short 4,long--->Long 5,cha ...
- jQuery中$()可以有两个参数
jQuery(expression, [context]) 返回值:jQuery 概述 这个函数接收一个包含 CSS 选择器的字符串,然后用这个字符串去匹配一组元素. jQuery 的核心功能都是通过 ...
- 值不能为null.参数名: viewInfo,如何解决
有蓝队网络服务器租用客户反映在一台服务器上使用数据库管理工具时弹出了如下错误 :值不能为null.参数名: viewInfo (Microsoft.SqlServer.Management.SqlSt ...