题目链接

戳我

\(Solution\)

我们观察发现循环格要满足每个点的入度都为\(1\)

证明:

我们假设每个点的入读不一定为\(1\),那么必定有一个或多个点的入度为0,那么则不满足循环格的定义,所以假设错误。所以每个点的入度必然为1。

所以这样我们就可以开始建图了。先进行拆点操作,将每个点拆成\(x\)和\(x'\)将\(x\)和\(S\)连接,流量为\(1\),费用为\(0\)再将\(x'\)和\(T\)连接,流量为\(1\),费用为\(0\)

最后对于每个点\(x\)将它和四周的\('\)点相连接。流量为1,费用的话在判断一下方向和字符是否相同,如果相同为\(0\),不同为\(1\)

\(end.\)

\(Code\)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int read() {
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
f=(c=='-')?-1:1,c=getchar();
while(c>='0'&&c<='9')
x=x*10+c-'0',c=getchar();
return x*f;
}
struct node {
int to,next,v,w;
} a[1000001];
int dis[10001],f[10001],pre[10001],fa[10001],s,t,n,m,head[10001],cnt,x,y,z,c;
void add(int x,int y,int c,int v) {
a[++cnt].to=y;
a[cnt].next=head[x];
a[cnt].v=c;
a[cnt].w=v;
head[x]=cnt;
}
queue < int > q;
int spfa() {
q.push(s);
memset(dis,127,sizeof(dis));
memset(f,0,sizeof(f));
f[s]=1,dis[s]=0;
int inf=dis[s+1];
while(!q.empty()) {
int now=q.front();
q.pop();
f[now]=0;
for(int i=head[now]; i; i=a[i].next) {
int v=a[i].to;
if(dis[v]>dis[now]+a[i].w&&a[i].v) {
dis[v]=dis[now]+a[i].w,pre[v]=i,fa[v]=now;
if(!f[v])
f[v]=1,q.push(v);
}
}
}
if(dis[t]!=inf)
return 1;
return 0;
}
int ans1,ans;
void anser() {
while(spfa()) {
int minx=2147483647;
for(int i=t; i!=s; i=fa[i])
minx=min(minx,a[pre[i]].v);
ans+=minx,ans1+=dis[t]*minx;
for(int i=t; i!=s; i=fa[i])
a[pre[i]].v-=minx,(pre[i]%2)?a[pre[i]+1].v+=minx:a[pre[i]-1].v+=minx;
}
}
char hh[10]= {'0','D','U','L','R'};
int fx[10]= {0,1,-1,0,0};
int fy[10]= {0,0,0,-1,1};
char ss[101][101],l[1001];
int main() {
int N=read(),M=read();
s=0,t=N*M*10,n=N*M;
for(int i=1; i<=n; i++)
add(s,i,1,0),add(i,s,0,0);
for(int i=1; i<=n; i++)
add(i+n,t,1,0),add(t,i+n,0,0);
for(int i=1; i<=N; i++) {
cin>>l;
for(int j=0; j<M; j++)
ss[i][j+1]=l[j];
}
for(int i=1; i<=N; i++)
for(int j=1; j<=M; j++) {
char pp=ss[i][j];
for(int k=1; k<=4; k++) {
int X=(i+fx[k]+N-1)%N+1,Y=(j+fy[k]+M-1)%M+1;
int now=(i-1)*M+j,nex=(X-1)*M+n+Y,o=(pp==hh[k])^1;
add(now,nex,1,o),add(nex,now,0,-o);
}
}
anser();
printf("%d",ans1);
}

最新文章

  1. java.net.SocketException: Connection reset
  2. 【BZOJ-3627】路径规划 分层图 + Dijkstra + spfa
  3. [Maven] - 安装与Eclipse搭建
  4. centos 7.0 ssh 登陆
  5. 如何在一个网站或者一个页面规划JS
  6. SQLAlchemy 中文文档翻译计划
  7. C#中的yield return与Unity中的Coroutine(协程)(下)
  8. hanio 塔和递规的理解。
  9. dedecms 文章内容文章名字和文章网址的调用
  10. IOS深入学习(1)之图标文件(icon files)
  11. 美版SOLOWHEEL与盗版SOLOWHEEL-IPS独轮车终极PK【图】_厂商资讯_太平洋电脑网
  12. mybatis入门-第一个程序
  13. 201521123095 《Java程序设计》第3周学习总结
  14. 算法提高 P1001
  15. CentOS7安装codeblocks(转载)
  16. Kafka简介、基本原理、执行流程与使用场景
  17. 关于VMware Linux 虚拟机忘记root 密码找回
  18. 五、git创建及合并分支
  19. B树学习总结
  20. stm32型号解读

热门文章

  1. 012. MVC5中Razor引擎使用模板页
  2. andriod/ios webview与js交互 html_demo
  3. VMware80端口映射
  4. 使用Easy-creds创建伪AP
  5. 虚拟机在 OpenStack 里没有共享存储条件下的在线迁移
  6. springboot成神之——spring jdbc的使用
  7. Visual C++ Samples-------------Code Project
  8. shelve和hashlib模块
  9. solr java api 使用solrj操作zookeeper集群中的solrCloud中的数据
  10. DataSet、DataTable转换List(泛型集合与DataSet互相转换 )