不难发现,每个点出度显然为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的更多相关文章

  1. BZOJ3171 Tjoi2013 循环格

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

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

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

  3. bzoj3171: [Tjoi2013]循环格(费用流)

    传送门 其实这题的建图并不难(虽然我并没有想出来) 首先,每一个点的入度和出度必须为$1$ 那么我们考虑拆点 每个点的出度点向它能到达的点的入度点连边,容量$1$,如果方向为原来的方向则费用$0$否则 ...

  4. 【BZOJ3171】[TJOI2013] 循环格(网络流)

    点此看题面 大致题意: 给你一个循环格,每个格子有一个方向.问你至少修改多少格子,才能使从每个格子出发都能回到原格子. 建图 这是道网络流题目,主要就是考虑如何建图. 我们可以把每个点拆成两个点,一个 ...

  5. 【bzoj3171】[Tjoi2013]循环格

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

  6. [bzoj3171]循环格

    如果把这个矩阵看成一张图,题目相当于要求每一个点的入度和出度都是1(也就是有很多环),否则指向环的点就无法走回自己了将所有点拆成两个,S向原来的点流(1,0)的边,拆出来的点向T连(1,0)的边,然后 ...

  7. [转载]hzwer的bzoj题单

    counter: 664BZOJ1601 BZOJ1003 BZOJ1002 BZOJ1192 BZOJ1303 BZOJ1270 BZOJ3039 BZOJ1191 BZOJ1059 BZOJ120 ...

  8. Topcoder SRM570 D1L3 CurvyonRails

    几个样例: 5 5wCCwwwCC....w......www..wReturns: 0 3 3C.w....C.Returns: 1 21 20CC..CCCw.CwC..CC.w.CC.CCCwC ...

  9. 网络流专题练习Day2

    04/17  目前做了:题 由于目前六道都是1A感觉非常爽... BZOJ1412: [ZJOI2009]狼和羊的故事 “狼爱上羊啊爱的疯狂,谁让他们真爱了一场:狼爱上羊啊并不荒唐,他们说有爱就有方向 ...

随机推荐

  1. [leetcode] 403. Frog Jump

    https://leetcode.com/contest/5/problems/frog-jump/ 这个题目,还是有套路的,之前做过一道题,好像是贪心性质,就是每次可以跳多远,最后问能不能跳到最右边 ...

  2. Hibernate3.3 小记

    //----------------事务(修改.删除.保存) Session s=getSession(); Transaction t=s.beginTransaction(); getSessio ...

  3. 没用调用flush导致的数据保存丢失

    在将字符串保存到文件时,我们采有下面的写法,大部分情况下,都可以直接将数据保存到文件中, using (var fs = System.IO.File.Create(path)) { var sw = ...

  4. 使用webstorm上传代码到github

    使用webstorm上传代码到github 字数681 阅读330 评论0 喜欢5 之前使用过webstorm上传代码到github,过了几个月竟然发现自己忘记了,好记性不如烂笔头啊,今天又重新用了一 ...

  5. 【BZOJ】1925: [Sdoi2010]地精部落 DP+滚动数组

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1925 题意:输入一个数N(1 <= N <= 4200),问将这些数排列成折线 ...

  6. MVC-起始页面设置

    MVC的URL是通过路由映射的,因为我们可以通过修改RouteConfig来改变应用的起始页面. public class RouteConfig { public static void Regis ...

  7. qt 5 小练习 纯代码制作自定义按钮

    大家都知道QT设计师中直接拖动的按钮是长方形带有圆角的图案,那我们如何来设置自定义按钮呢 要设计一个按钮,我们必须要知道按钮有什么属性,首先,按钮必须有一个位置 第二,按钮必须有一个名称.还有当我们点 ...

  8. theano log softmax 4D

    def softmax_4d(x_4d): """ x_4d: a 4D tensor:(batch_size,channels, height, width) &quo ...

  9. css3360度旋转动画

    @-webkit-keyframes Parallaxs{ from { -webkit-transform: rotate(180deg) ; -moz-transform: rotate(180d ...

  10. BZOJ 1729: [Usaco2005 dec]Cow Patterns 牛的模式匹配

    Description 约翰的N(1≤N≤100000)只奶牛中出现了K(1≤K≤25000)只爱惹麻烦的坏蛋.奶牛们按一定的顺序排队的时候,这些坏蛋总会站在一起.为了找出这些坏蛋,约翰让他的奶牛排好 ...