当前位置: 首页 > news >正文

3171. [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

 

原题题意即为将图转化成每个点入度出度恰好为1
拆点,拆成入点和出点
向本来指向的边连费用为0的边
向周围的边连费用为1的边

 

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<queue>
  6 #define id(x,y) (x-1)*m+y
  7 #define N (10000+10)
  8 #define M (1000000+10)
  9 using namespace std;
 10 bool used[N];
 11 int n,m,s,e,z,Ans,a[101][101];
 12 int num_edge,head[N];
 13 int dis[N],INF,pre[N];
 14 int dx[5]= {0,-1,1,0,0},dy[5]= {0,0,0,-1,1};
 15 char st[101];
 16 queue<int>q;
 17 struct node
 18 {
 19     int to,next,Flow,Cost;
 20 } edge[M*2];
 21 
 22 void add(int u,int v,int l,int c)
 23 {
 24     edge[++num_edge].to=v;
 25     edge[num_edge].next=head[u];
 26     edge[num_edge].Flow=l;
 27     edge[num_edge].Cost=c;
 28     head[u]=num_edge;
 29 }
 30 
 31 bool Spfa(int s,int e)
 32 {
 33     memset(dis,0x7f,sizeof(dis));
 34     memset(pre,-1,sizeof(pre));
 35     dis[s]=0;
 36     used[s]=true;
 37     q.push(s);
 38     while (!q.empty())
 39     {
 40         int x=q.front();
 41         q.pop();
 42         for (int i=head[x]; i!=0; i=edge[i].next)
 43             if (dis[x]+edge[i].Cost<dis[edge[i].to] && edge[i].Flow>0)
 44             {
 45                 dis[edge[i].to]=dis[x]+edge[i].Cost;
 46                 pre[edge[i].to]=i;
 47                 if (!used[edge[i].to])
 48                 {
 49                     used[edge[i].to]=true;
 50                     q.push(edge[i].to);
 51                 }
 52             }
 53         used[x]=false;
 54     }
 55     return dis[e]!=INF;
 56 }
 57 
 58 int MCMF(int s,int e)
 59 {
 60     int Fee=0;
 61     while (Spfa(s,e))
 62     {
 63         int d=INF;
 64         for (int i=e; i!=s; i=edge[((pre[i]-1)^1)+1].to)
 65             d=min(d,edge[pre[i]].Flow);
 66         for (int i=e; i!=s; i=edge[((pre[i]-1)^1)+1].to)
 67         {
 68             edge[pre[i]].Flow-=d;
 69             edge[((pre[i]-1)^1)+1].Flow+=d;
 70         }
 71         Fee+=d*dis[e];
 72     }
 73     return Fee;
 74 }
 75 
 76 int main()
 77 {
 78     memset(&INF,0x7f,sizeof(INF));
 79     s=0,e=10001;
 80     scanf("%d%d",&n,&m);
 81     for (int i=1; i<=n; ++i)
 82     {
 83         scanf("%s",st);
 84         for (int j=1; j<=m; ++j)
 85         {
 86             if (st[j-1]=='U') a[i][j]=1;
 87             if (st[j-1]=='D') a[i][j]=2;
 88             if (st[j-1]=='L') a[i][j]=3;
 89             if (st[j-1]=='R') a[i][j]=4;
 90             add(s,id(i,j),1,0);
 91             add(id(i,j),s,0,0);
 92             add(id(i,j)+m*n,e,1,0);
 93             add(e,id(i,j)+m*n,0,0);
 94         }
 95     }
 96     for (int i=1; i<=n; ++i)
 97         for (int j=1; j<=m; ++j)
 98             for (int k=1; k<=4; ++k)
 99             {
100                 int x=i+dx[k],y=j+dy[k];
101                 if (x<1) x=n;
102                 if (x>n) x=1;
103                 if (y<1) y=m;
104                 if (y>m) y=1;
105                 add(id(i,j),id(x,y)+m*n,1,(k!=a[i][j]));
106                 add(id(x,y)+m*n,id(i,j),0,-(k!=a[i][j]));
107             }
108     printf("%d",MCMF(s,e));
109 }

 

转载于:https://www.cnblogs.com/refun/p/8682316.html

相关文章:

  • Android OTG之USB转串口模块通讯
  • 扑克千术
  • 删除数据库中所有表
  • 初来乍到
  • .NET成年了,然后呢?
  • android 线程消息深入
  • ios动态库和静态库
  • Chrome开发——第一个博客链接插件
  • RabbitMQ消息队列(九):Publisher的消息确认机制
  • 减治算法求n个数中的最小数的位置
  • spark2.1.0 自定义AccumulatorV2累加少值(线程不安全)?
  • heartbeat+ldirectord实现web与dns的高可用性
  • __new__ 是什么鬼
  • C#面向对象20 序列化和反序列化
  • SecureCRT 只用 RZ 命令上传大文件失败
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • [译]如何构建服务器端web组件,为何要构建?
  • Java的Interrupt与线程中断
  • Koa2 之文件上传下载
  • rc-form之最单纯情况
  • spring boot 整合mybatis 无法输出sql的问题
  • SpringBoot 实战 (三) | 配置文件详解
  • ucore操作系统实验笔记 - 重新理解中断
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 每天一个设计模式之命令模式
  • 前端js -- this指向总结。
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • ​io --- 处理流的核心工具​
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • #pragma 指令
  • $$$$GB2312-80区位编码表$$$$
  • ()、[]、{}、(())、[[]]命令替换
  • (2022 CVPR) Unbiased Teacher v2
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (Git) gitignore基础使用
  • (安卓)跳转应用市场APP详情页的方式
  • (二)c52学习之旅-简单了解单片机
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (九)信息融合方式简介
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (六)Hibernate的二级缓存
  • (三) diretfbrc详解
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • .net 使用ajax控件后如何调用前端脚本
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .net对接阿里云CSB服务
  • .net中应用SQL缓存(实例使用)
  • @data注解_SpringBoot 使用WebSocket打造在线聊天室(基于注解)
  • @select 怎么写存储过程_你知道select语句和update语句分别是怎么执行的吗?
  • [23] GaussianAvatars: Photorealistic Head Avatars with Rigged 3D Gaussians
  • [android] 请求码和结果码的作用
  • [ASP.NET 控件实作 Day7] 设定工具箱的控件图标