bzoj3171
不难发现,每个点出度显然为1,要想整个图形成环,必然每个点的入度也为1;
所以,不难想到将每个点i拆成两个点i1,i2构成二分图,
连边s--->i1 流量为1,费用为0,i2--->t流量为1,费用为0
这样左右两边的点都只能匹配1次,也就满足了出入度为1;
对于点i的上下左右4个点,分别连i1--->j2,容量为1;
对于点i原来指向的点,之间边的费用为0,否则费用为1,表示要修改1次
然后最小费用最大流即可
注意这道题最左边的点超出边界后自动到达最右边的点
const inf=;
dx:array[..] of integer=(-,,,);
dy:array[..] of integer=(,,-,); type node=record
flow,cost,point,next:longint;
end; var edge:array[..] of node;
p,cur,pre,d:array[..] of longint;
q:array[..] of longint;
v:array[..] of boolean;
num,kind:array[..,..] of longint;
len,x,y,i,j,n,m,h,c,k,t:longint;
s:string; procedure add(x,y,f,c:longint);
begin
inc(len);
edge[len].point:=y;
edge[len].flow:=f;
edge[len].cost:=c;
edge[len].next:=p[x];
p[x]:=len;
end; function spfa:boolean;
var f,r,x,y:longint;
begin
q[]:=;
f:=;
r:=;
for i:= to t do
d[i]:=inf;
d[]:=;
fillchar(v,sizeof(v),false);
v[]:=true;
while f<=r do
begin
x:=q[f];
v[x]:=false;
i:=p[x];
while i<>- do
begin
y:=edge[i].point;
if edge[i].flow> then
begin
if d[x]+edge[i].cost<d[y] then
begin
d[y]:=edge[i].cost+d[x];
pre[y]:=x;
cur[y]:=i;
if not v[y] then
begin
v[y]:=true;
inc(r);
q[r]:=y;
end;
end;
end;
i:=edge[i].next;
end;
inc(f);
end;
if d[t]=inf then exit(false) else exit(true);
end; function mincost:longint;
var i,j:longint;
begin
mincost:=;
while spfa do
begin
i:=t;
while i<> do
begin
j:=cur[i];
dec(edge[j].flow);
inc(edge[j xor ].flow);
i:=pre[i];
end;
mincost:=mincost+d[t];
end;
end; begin
len:=-;
fillchar(p,sizeof(p),);
readln(n,m);
for i:= to n do
begin
readln(s);
for j:= to m do
begin
inc(h);
num[i,j]:=h;
if s[j]='U' then kind[i,j]:=;
if s[j]='D' then kind[i,j]:=;
if s[j]='L' then kind[i,j]:=;
if s[j]='R' then kind[i,j]:=;
end;
end;
t:=n*m*+;
for i:= to n do
begin
for j:= to m do
begin
add(,num[i,j],,);
add(num[i,j],,,);
add(num[i,j]+h,t,,);
add(t,num[i,j]+h,,);
for k:= to do
begin
x:=i+dx[k];
y:=j+dy[k];
if x= then x:=n;
if x=n+ then x:=;
if y= then y:=m;
if y=m+ then y:=;
if kind[i,j]=k then c:= else c:=;
add(num[i,j],num[x,y]+h,inf,c);
add(num[x,y]+h,num[i,j],,-c);
end;
end;
end;
writeln(mincost);
end.
bzoj3171的更多相关文章
- BZOJ3171 Tjoi2013 循环格
传送门 Description 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位置(r,c) ,你可以沿着箭头 ...
- [TJOI2013]循环格 费用流 BZOJ3171
题目背景 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位(r,c),你可以沿着箭头方向在格子间行走.即:如果 ...
- bzoj3171: [Tjoi2013]循环格(费用流)
传送门 其实这题的建图并不难(虽然我并没有想出来) 首先,每一个点的入度和出度必须为$1$ 那么我们考虑拆点 每个点的出度点向它能到达的点的入度点连边,容量$1$,如果方向为原来的方向则费用$0$否则 ...
- 【BZOJ3171】[TJOI2013] 循环格(网络流)
点此看题面 大致题意: 给你一个循环格,每个格子有一个方向.问你至少修改多少格子,才能使从每个格子出发都能回到原格子. 建图 这是道网络流题目,主要就是考虑如何建图. 我们可以把每个点拆成两个点,一个 ...
- 【bzoj3171】[Tjoi2013]循环格
题目描述: 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位置(r,c) ,你可以沿着箭头防线在格子间行走.即 ...
- [bzoj3171]循环格
如果把这个矩阵看成一张图,题目相当于要求每一个点的入度和出度都是1(也就是有很多环),否则指向环的点就无法走回自己了将所有点拆成两个,S向原来的点流(1,0)的边,拆出来的点向T连(1,0)的边,然后 ...
- [转载]hzwer的bzoj题单
counter: 664BZOJ1601 BZOJ1003 BZOJ1002 BZOJ1192 BZOJ1303 BZOJ1270 BZOJ3039 BZOJ1191 BZOJ1059 BZOJ120 ...
- Topcoder SRM570 D1L3 CurvyonRails
几个样例: 5 5wCCwwwCC....w......www..wReturns: 0 3 3C.w....C.Returns: 1 21 20CC..CCCw.CwC..CC.w.CC.CCCwC ...
- 网络流专题练习Day2
04/17 目前做了:题 由于目前六道都是1A感觉非常爽... BZOJ1412: [ZJOI2009]狼和羊的故事 “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向 ...
随机推荐
- 理解css 中的position五个属性
在实际开发页面布局时,运用position,对定位的块级元素的嵌套的效果总是不太理解,这里做了几个测试 一般的在w3c中我们可以很容易的获取定义: static : 默认值.没有定位,元素出现在正常的 ...
- Java实战之03Spring-01Spring概述
一.Spring概述 1.Spring是什么? Spring是分层的Java SE/EE应用 full-stack轻量级开源框架,以IoC(Inverse Of Control:反转控制)和AOP(A ...
- String Shifting
我们规定对一个字符串的shift操作如下:略去.shift(string, x) = string(0 <= x < n). 分析:一看这题,这不很简单么,直接模拟判断,但是这套路有这么简 ...
- Java如何获得平台相关的行分隔符、路径分隔符?
我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3550194.html ,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体 ...
- linux系统制作简单流程
制作嵌入式平台使用的Linux内 核, 方法和制作PC平台 的Linux内 核基本一致, 下面使用 对比的方式介绍如何制作用 于6410开发板的内 核. 1. 清除原有配置与中间文件x86: make ...
- Memcache存储大数据的问题
Memcached存储单个item最大数据是在1MB内,假设数据超过1M,存取set和get是都是返回false,并且引起性能的问题. 我们之前对排行榜的数据进行缓存,因为排行榜在我们全部sql se ...
- opengl混合效果
效果如下图:
- python实用函数
dir([obj]) 显示对象属性, 无参数显示全局变量的名字 help([obj]) 显示对象的文档字符串 int(obj) 将一个对象转换为整数 len(obj) 返回对象的长度 range([[ ...
- 【原创】一起学C++ 之enum ---------C++ primer plus(第6版)
枚举 定义:在默认情况下讲整数值赋给枚举量,第一个枚举量的值为0,第二个枚举量的值为1,依次+1 一.定义一个枚举,枚举类型,枚举量 *与C#相比个人认为C++的enum不好一点是不能通过枚举名点其中 ...
- 【JPA】两种不同的实现jpa的配置方法
两种不同的实现jpa的配置方法 第一种: com.mchange.v2.c3p0.ComboPooledDataSource datasource.connection.driver_class=co ...