不难发现,每个点出度显然为1,要想整个图形成环,必然每个点的入度也为1;
所以,不难想到将每个点i拆成两个点i1,i2构成二分图,
连边s--->i1 流量为1,费用为0,i2--->t流量为1,费用为0
这样左右两边的点都只能匹配1次,也就满足了出入度为1;
对于点i的上下左右4个点,分别连i1--->j2,容量为1;
对于点i原来指向的点,之间边的费用为0,否则费用为1,表示要修改1次
然后最小费用最大流即可
注意这道题最左边的点超出边界后自动到达最右边的点
1 const inf=10000007; 2 dx:array[1..4] of integer=(-1,1,0,0); 3 dy:array[1..4] of integer=(0,0,-1,1); 4 5 type node=record 6 flow,cost,point,next:longint; 7 end; 8 9 var edge:array[0..200100] of node; 10 p,cur,pre,d:array[0..10010] of longint; 11 q:array[0..20000] of longint; 12 v:array[0..500] of boolean; 13 num,kind:array[0..20,0..20] of longint; 14 len,x,y,i,j,n,m,h,c,k,t:longint; 15 s:string; 16 17 procedure add(x,y,f,c:longint); 18 begin 19 inc(len); 20 edge[len].point:=y; 21 edge[len].flow:=f; 22 edge[len].cost:=c; 23 edge[len].next:=p[x]; 24 p[x]:=len; 25 end; 26 27 function spfa:boolean; 28 var f,r,x,y:longint; 29 begin 30 q[1]:=0; 31 f:=1; 32 r:=1; 33 for i:=1 to t do 34 d[i]:=inf; 35 d[0]:=0; 36 fillchar(v,sizeof(v),false); 37 v[0]:=true; 38 while f<=r do 39 begin 40 x:=q[f]; 41 v[x]:=false; 42 i:=p[x]; 43 while i<>-1 do 44 begin 45 y:=edge[i].point; 46 if edge[i].flow>0 then 47 begin 48 if d[x]+edge[i].cost<d[y] then 49 begin 50 d[y]:=edge[i].cost+d[x]; 51 pre[y]:=x; 52 cur[y]:=i; 53 if not v[y] then 54 begin 55 v[y]:=true; 56 inc(r); 57 q[r]:=y; 58 end; 59 end; 60 end; 61 i:=edge[i].next; 62 end; 63 inc(f); 64 end; 65 if d[t]=inf then exit(false) else exit(true); 66 end; 67 68 function mincost:longint; 69 var i,j:longint; 70 begin 71 mincost:=0; 72 while spfa do 73 begin 74 i:=t; 75 while i<>0 do 76 begin 77 j:=cur[i]; 78 dec(edge[j].flow); 79 inc(edge[j xor 1].flow); 80 i:=pre[i]; 81 end; 82 mincost:=mincost+d[t]; 83 end; 84 end; 85 86 begin 87 len:=-1; 88 fillchar(p,sizeof(p),255); 89 readln(n,m); 90 for i:=1 to n do 91 begin 92 readln(s); 93 for j:=1 to m do 94 begin 95 inc(h); 96 num[i,j]:=h; 97 if s[j]='U' then kind[i,j]:=1; 98 if s[j]='D' then kind[i,j]:=2; 99 if s[j]='L' then kind[i,j]:=3; 100 if s[j]='R' then kind[i,j]:=4; 101 end; 102 end; 103 t:=n*m*2+1; 104 for i:=1 to n do 105 begin 106 for j:=1 to m do 107 begin 108 add(0,num[i,j],1,0); 109 add(num[i,j],0,0,0); 110 add(num[i,j]+h,t,1,0); 111 add(t,num[i,j]+h,0,0); 112 for k:=1 to 4 do 113 begin 114 x:=i+dx[k]; 115 y:=j+dy[k]; 116 if x=0 then x:=n; 117 if x=n+1 then x:=1; 118 if y=0 then y:=m; 119 if y=m+1 then y:=1; 120 if kind[i,j]=k then c:=0 else c:=1; 121 add(num[i,j],num[x,y]+h,inf,c); 122 add(num[x,y]+h,num[i,j],0,-c); 123 end; 124 end; 125 end; 126 writeln(mincost); 127 end.