3171: [Tjoi2013]循环格

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 741  Solved: 463
[Submit][Status][Discuss]

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

Source

 题解:
这道题就是让每个点都在至少一个环里。
于是就可以用费用流。
一个格子只能选一次,所以入度出度都为1。
然后拆点。
左边为出点,右边为入点。
从S向所有Xi连费用为0,容量为1的边。(从X出发)
Yi向T连费用为0,容量为1的边。(到达Y)
从X的Xi向Y的Yj连容量为1,费用为0。(原图中有的边)
原图中没有的剩下三个方向连容量为1,费用为1。
跑最小费用最大流即可。。。
 #include<bits/stdc++.h>
using namespace std;
#define INF 1e9
struct node
{
int begin,end,cap,value,next;
}edge[];
int cnt,Head[],c,S,T,ans,q[],dis[],from[];
bool vis[];
char a[][];
int fx[]={,,,-};
int fy[]={,-,,};
void addedge(int bb,int ee,int cc,int vv)
{
edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].cap=cc;edge[cnt].value=vv;edge[cnt].next=Head[bb];Head[bb]=cnt;
}
void addedge1(int bb,int ee,int cc,int vv)
{
addedge(bb,ee,cc,vv);addedge(ee,bb,,-vv);
}
int xy(int x,int y){return (x-)*c+y;}
int SPFA()
{
int head,tail,i,u,v;
head=;tail=;q[tail]=S;
for(i=;i<=T;i++)dis[i]=INF;dis[S]=;
memset(vis,false,sizeof(vis));vis[S]=true;
while(head!=tail)
{
head++;if(head==)head=;
u=q[head];
for(i=Head[u];i!=-;i=edge[i].next)
{
if(edge[i].cap>)
{
v=edge[i].end;
if(dis[u]+edge[i].value<dis[v])
{
dis[v]=dis[u]+edge[i].value;
from[v]=i;
if(vis[v]==false)
{
vis[v]=true;
tail++;if(tail==)tail=;
q[tail]=v;
}
}
}
}
vis[u]=false;
}
if(dis[T]<INF)return ;
else return ;
}
void MCF()
{
int F=INF,i;
for(i=from[T];i;i=from[edge[i].begin])F=min(F,edge[i].cap);
for(i=from[T];i;i=from[edge[i].begin]){edge[i].cap-=F,edge[i^].cap+=F;ans+=F*edge[i].value;}
//ans+=dis[T];
memset(from,,sizeof(from));
}
int main()
{
int r,i,j,k,XY,x1,y1;
scanf("%d %d",&r,&c);
for(i=;i<=r;i++)
{
scanf("\n%s",a[i]+);
}
S=;T=;
memset(Head,-,sizeof(Head));cnt=;
for(i=;i<=r;i++)
{
for(j=;j<=c;j++)
{
XY=xy(i,j);
addedge1(S,XY,,);
addedge1(XY+,T,,);
for(k=;k<=;k++)
{
x1=i+fx[k];
y1=j+fy[k];
if(x1<)x1=r;if(x1>r)x1=;
if(y1<)y1=c;if(y1>c)y1=;
if(a[i][j]=='U'&&k==){addedge1(XY,xy(x1,y1)+,,);continue;}
if(a[i][j]=='D'&&k==){addedge1(XY,xy(x1,y1)+,,);continue;}
if(a[i][j]=='L'&&k==){addedge1(XY,xy(x1,y1)+,,);continue;}
if(a[i][j]=='R'&&k==){addedge1(XY,xy(x1,y1)+,,);continue;}
addedge1(XY,xy(x1,y1)+,,);
}
/*if(a[i][j]=='U')
{
if(i-1>=1)addedge1(XY,xy(i-1,j)+300,1,0);
else addedge1(XY,xy(r,j)+300,1,0);
}
else if(a[i][j]=='D')
{
if(i+1<=r)addedge1(XY,xy(i+1,j)+300,1,0);
else addedge1(XY,xy(1,j)+300,1,0);
}
else if(a[i][j]=='L')
{
if(j-1>=1)addedge1(XY,xy(i,j-1)+300,1,0);
else addedge1(XY,xy(i,c)+300,1,0);
}
else
{
if(j+1<=c)addedge1(XY,xy(i,j+1)+300,1,0);
else addedge1(XY,xy(i,1)+300,1,0);
}*/
}
}
ans=;
while(SPFA())MCF();
printf("%d",ans);
return ;
}

Bzoj 3171: [Tjoi2013]循环格 费用流的更多相关文章

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

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

  2. bzoj 3171: [Tjoi2013]循环格

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

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

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

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

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

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

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

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

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

  7. 3171. [TJOI2013]循环格【费用流】

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

  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. tomcat内存溢出问题

    内存泄露java.lang.OutOfMemoryError: PermGen space解决办法 今天访问web服务器,tomcat服务就瘫痪了,通过查看日志,发现java.lang.OutOfMe ...

  2. 相看系统中用户的信息 passwd, shadow

    用用户的信息都保存在 etc/passwd 和 etc/shadow 文件中,其中 shadow 保存的是经过加密码的 能过 cat etc/passwd 和 cat etc/shadow 来查看相关 ...

  3. php类的属性

    属性声明是由关键字 public,protected 或者 private 开头,后面跟一个普通的变量声明来组成.属性的变量可以设置初始化的默认值,默认值必须是常量. class Car { //定义 ...

  4. XML1_XML基础

    1.XML的作用 XML 被设计用来传输和存储数据.所以XML 是不作为的. 2.简单的描述 XML 文档形成一种树结构. XML 文档必须包含根元素.该元素是所有其他元素的父元素.XML 文档中的元 ...

  5. 压缩代码加速ecshop程序页面加载速度

    由于页面有很多图片,页面加载速度有点慢,本来打算减小图片的体积,后来想想这个后期还得测试下,所以暂时不打算使用google的图片优化工具,先把ecshop生成的html代码压缩下吧 压缩前:首页体积为 ...

  6. 例行性工作排程 (crontab)

    1. 什么是例行性工作排程 1.1 Linux 工作排程的种类: at, crontab 1.2 Linux 上常见的例行性工作2. 仅运行一次的工作排程 2.1 atd 的启动与 at 运行的方式: ...

  7. android中LayoutInflater详解与使用

    android的LayoutInflater用来得到一个布局文件,也就是xxx.xml,而我们常用的findviewbyid是用来取得布局文件里的控件或都布局.inflater即为填充的意思,也就是说 ...

  8. Java基础类型自动装箱(autoboxing)

    Java SE 1.5 版本及之后,开始提供自动装箱功能. 自动装箱,将基础类型“包装”成一种类型: 基本类型 -->  包装器类 如下过程可触发自动装箱过程: Integer count = ...

  9. jQuery预加载插件

      插件描述:jQuery Fadeloader的插件可以让你轻松实现预加载到您的网站或部分使用级联渐显效果来显示特定的内容块(例如,头> MENU>内容>页脚) jQuery Fa ...

  10. Word添加新编号

    要用到(1)(2),不想手写,但是word只有1.2.3和1)2)3),我就自定义哦.