BZOJ3171:[TJOI2013]循环格

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

 

题解:

把原图看做是基环树,则要求每个点都在环上,即每个点有且只有一个子节点。

把每个点拆成两个,我们得到了一个二分图匹配的模型,其中有些匹配边有代价。

跑km或费用流即可。

 

代码:

 1 const
 2   fx:array[1..4]of longint=(0,1,0,-1);
 3   fy:array[1..4]of longint=(1,0,-1,0);
 4 var
 5   o,v:array[0..1600] of boolean;
 6   f,s,d,dis:array[0..1600] of longint;
 7   next,p,c,w:array[-100000..100000] of longint;
 8   i,j,k,ii,jj,l,y,t,ss,tt,n,m,ans,imp,flow:longint;
 9   ch:array[0..20,0..20]of char;
10 procedure link(i,j,k,l:longint);
11 begin
12   inc(t);
13   next[t]:=d[i]; d[i]:=t; p[t]:=j; c[t]:=k; w[t]:=l;
14   next[-t]:=d[j]; d[j]:=-t; p[-t]:=i; w[-t]:=-l;
15 end;
16 function dfs(i,flow:longint):longint;
17 var j,k,l,min:longint;
18 begin
19   if i=tt then
20   begin
21     inc(ans,dis[i]*flow); exit(flow);
22   end;
23   k:=s[i]; j:=p[k]; dfs:=0;
24   o[i]:=true; v[i]:=true;
25   while k<>0 do
26   begin
27     l:=dis[i]+w[k]-dis[j]; min:=flow;
28     if c[k]<min then min:=c[k];
29     if(min>0)and(l<f[j])then f[j]:=l;
30     if(min>0)and(l=0)and(not o[j])then
31     begin
32       l:=dfs(j,min);
33       inc(dfs,l); dec(flow,l);
34       dec(c[k],l); inc(c[-k],l);
35     end;
36     if flow=0 then break;
37     s[i]:=next[s[i]];
38     k:=s[i]; j:=p[k];
39   end;
40   o[i]:=false;
41 end;
42 begin
43   readln(n,m);
44   ss:=0; tt:=n*m*2+1;
45   for i:=1 to n do
46   begin
47     for j:=1 to m do read(ch[i,j]);
48     readln;
49   end;
50   for i:=1 to n do
51   for j:=1 to m do
52   begin
53     link(ss,m*(i-1)+j,1,0); link(n*m+m*(i-1)+j,tt,1,0);
54     begin
55       k:=1; ii:=i-1; jj:=j; if ii=0 then ii:=n;
56       if ch[i,j]='U' then k:=0;
57       link(m*(i-1)+j,n*m+m*(ii-1)+jj,1,k);
58     end;
59     begin
60       k:=1; ii:=i; jj:=j-1; if jj=0 then jj:=m;
61       if ch[i,j]='L' then k:=0;
62       link(m*(i-1)+j,n*m+m*(ii-1)+jj,1,k);
63     end;
64     begin
65       k:=1; ii:=i+1; jj:=j; if ii>n then ii:=1;
66       if ch[i,j]='D' then k:=0;
67       link(m*(i-1)+j,n*m+m*(ii-1)+jj,1,k);
68     end;
69     begin
70       k:=1; ii:=i; jj:=j+1; if jj>m then jj:=1;
71       if ch[i,j]='R' then k:=0;
72       link(m*(i-1)+j,n*m+m*(ii-1)+jj,1,k);
73     end;
74   end;
75   repeat
76     for i:=ss to tt do s[i]:=d[i];
77     fillchar(v,sizeof(v),false);
78     fillchar(f,sizeof(f),1);
79     inc(flow,dfs(ss,1 shl 20));
80     imp:=1 shl 20;
81     for i:=ss to tt do
82     if(not v[i])and(f[i]<imp)then imp:=f[i];
83     for i:=ss to tt do if not v[i] then inc(dis[i],imp);
84   until imp=1 shl 20;
85   writeln(ans);
86 end.
View Code
posted @ 2017-03-07 11:05  GhoStreach  阅读(156)  评论(0编辑  收藏  举报