【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 ...
随机推荐
- Python 内置函数super
super()函数是用于调用父类/超类的一个方法 super是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没有问题,但是如果使用多继承,会涉及到查找顺序(MRO),重复调用(钻石继 ...
- D-多连块拼图
多连块是指由多个等大正方形边与边连接而成的平面连通图形. – 维基百科 给一个大多连块和小多连块,你的任务是判断大多连块是否可以由两个这样的小多连块拼成.小多连块只能平移,不能旋转或者翻转.两个小多连 ...
- xilinx基础入门
2019.09.03 一.基础部分及语法 一.FPGA程序的固化 [USF-XSim-62] 'simulate' step failed with errors. Please check the ...
- Django文档——Model中的ForeignKey,ManyToManyField与OneToOneField 关联关系字段 (Relationship fields)
ForeignKey,ManyToManyField与OneToOneField分别在Model中定义多对一,多对多,一对一关系. 例如,一本书由一家出版社出版,一家出版社可以出版很多书.一本书由多个 ...
- 爬虫之selenium 安装与 chromedriver安装
今天学到一个有意思的插件,就是chromedriver,在爬虫的时候,如果网站反爬虫做的很好,自己又很想爬去里面的数据,那就可以用这个插件,虽然笨笨的,慢的一批,但是还有别的办法就不会用他啦, 这个东 ...
- spark数据结构之RDD
学习spark,RDD是一个逃不过去的话题,那么接下来我们看看RDD 1.什么是RDD? RDD叫做弹性分布式数据集,是Spark中最基本的数据抽象,代表一个不可变.可分区.里面元素可以并行计算的集合 ...
- unittest加载用例
diascover加载测试用例 1.discover方法里面有三个参数: -case_dir:这个是待执行用例的目录. -pattern:这个是匹配脚本名称的规则,test*.py意思是匹配test开 ...
- MySQL索引优化(索引三表优化案例)
建表SQL phone.book表建立索引 [关联优化查询建议] 1.保证被驱动表的join字段已经被索引 被驱动表 join 后的表为被驱动表 (需要被查询) 2.left join 时,选择小 ...
- #include <xxx.h>和#include "xxx.h"的区别
<>代表在系统目录下查找该头文件(系统定义头文件) ""代表在用户目录下查找该头文件(自定义头文件)
- linux MySql 在 Master 主从复制配置
在 Master 服务器上建立用于 Slave 服务器复制数据的帐户 [root@master ~]# mysql mysql> grant replication slave,replicat ...