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

[TJOI2013]循环格

  

题目背景

一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子。每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0)。给定一个起始位(r,c),你可以沿着箭头方向在格子间行走。即:如果(r,c)是一个左箭头,那么走到(r,c-1);如果是一个右箭头,走到(r,c+1);如果是上箭头,走到(r-1,c);如果是下箭头,走到(r+1,c)。每一行和每一列都是循环的,即如果走出边界,你会出现在另一侧。比如在一个5*5的循环格里,从(3,0)向左走会出现在(3,4)。

题目描述

一个完美的循环格是这样定义的:对于任意一个起始位置,你都可以沿着箭头最终回到起始位置。如果一个循环格不满足完美,你可以随意修改任意一个元素的箭头直到完美。例如下图,左边不是一个完美的循环格,因为只有从(1,1),(1,2),(2,0),(2,3)出发才会回到起始位置。通过修改其中两个箭头,可以得到右图,一个完美的循环格。

给定一个循环格,你需要计算最少需要修改多少个元素使其完美。

输入输出格式

输入格式:

 

第一行两个整数R和C,表示循环格的行和列。接下来R行,每一行包含C个字符LRUD表示左右上下

 

输出格式:

 

一个整数,表示最少需要修改多少个元素使得给定的循环格完美。

 

输入输出样例

输入样例#1:
4 4
RRRD
URDD
UULD
ULLL
输出样例#1:
0
输入样例#2: 
3 4
RRRD
URLL
LRRR
输出样例#2:
2

说明

数据范围

30%的数据,1 ≤ R, C ≤ 7

100%的数据,1 ≤ R, C ≤ 15

 

如果把网格中的点看成图中的点,可以发现每个点的出度都是1。

而满足条件的图肯定是若干个简单环,所以这就要求每个点的入度也是1。

然后就可以二分图匹配了,不过因为如果按照原来的方向走的话是不需要改变的,

所以还需要引入费用,跑一个最小费用最大流就行了。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#define ll long long
#define maxn 10005
#define pb push_back
using namespace std;
const int inf=1<<29;
vector<int> g[maxn]; 
struct lines{
    int from,to,flow,cap,cost;
}l[maxn*20];
int t=-1,S,T,n,m;
int d[maxn],p[maxn];
int a[maxn],ans=0;
bool iq[maxn];

inline void add(int from,int to,int cap,int cost){
    l[++t]=(lines){from,to,0,cap,cost},g[from].pb(t);
    l[++t]=(lines){to,from,0,0,-cost},g[to].pb(t);
}

inline bool BFS(){
    queue<int> q;
    memset(d,0x3f,sizeof(d));
    p[S]=0,a[S]=inf,iq[S]=1;
    d[S]=0,q.push(S);
    
    int x; lines e;
    while(!q.empty()){
        x=q.front(),q.pop();
        
        for(int i=g[x].size()-1;i>=0;i--){
            e=l[g[x][i]];
            if(e.flow<e.cap&&d[x]+e.cost<d[e.to]){
                d[e.to]=d[x]+e.cost;
                p[e.to]=g[x][i];
                a[e.to]=min(a[x],e.cap-e.flow);
                if(!iq[e.to]) iq[e.to]=1,q.push(e.to); 
            }
        }
        
        iq[x]=0;
    }
    
    if(d[T]==d[T+1]) return 0;
    
    ans+=a[T]*d[T];
    
    int now=T,pre;
    while(now!=S){
        pre=p[now];
        l[pre].flow+=a[T];
        l[pre^1].flow-=a[T];
        now=l[pre].from;
    }
    
    return 1;
}

inline void MFMC(){
    while(BFS());
}

//上1下2左3右4 
int id[25][25],num;
int val[maxn][6],dy[666];
char ch;

int main(){
    dy['L']=3,dy['R']=4;
    dy['U']=1,dy['D']=2;
    
    scanf("%d%d",&n,&m),S=0,T=2*n*m+1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            id[i][j]=++num;
            ch=getchar();
            while(!dy[ch]) ch=getchar();
            val[num][dy[ch]]=1;
        }
    
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            int now=id[i][j];
            if(i==1) add(now,id[n][j]+num,1,val[now][1]^1);
            else add(now,id[i-1][j]+num,1,val[now][1]^1);
            
            if(i==n) add(now,id[1][j]+num,1,val[now][2]^1);
            else add(now,id[i+1][j]+num,1,val[now][2]^1);
            
            if(j==1) add(now,id[i][m]+num,1,val[now][3]^1);
            else add(now,id[i][j-1]+num,1,val[now][3]^1);
            
            if(j==m) add(now,id[i][1]+num,1,val[now][4]^1);
            else add(now,id[i][j+1]+num,1,val[now][4]^1);
        }
    
    
    for(int i=1;i<=num;i++){
        add(S,i,1,0);
        add(i+num,T,1,0);
    }
    
    MFMC();
    printf("%d\n",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/JYYHH/p/8358214.html

相关文章:

  • 6. python 字符串格式化表达式
  • tomcat 取消项目名访问路径
  • 【Python】学习笔记5-模块pymysql操作mysql数据库
  • mysql innodb myisam 比较
  • Git 安装配置
  • typeof面试题解答
  • 辩证看待 iostat
  • RpcContext
  • mysql学习笔记(1)--varChar和char类型的区别
  • etcd raft library
  • jQuery数组去重复
  • Nginx 配置文件重写
  • python------并发编程
  • freebsd安装python2
  • js为什么是单线程的?10分钟了解js引擎的执行机制
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • “大数据应用场景”之隔壁老王(连载四)
  • angular组件开发
  • Debian下无root权限使用Python访问Oracle
  • egg(89)--egg之redis的发布和订阅
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • ES学习笔记(12)--Symbol
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • node入门
  • PHP面试之三:MySQL数据库
  • SAP云平台里Global Account和Sub Account的关系
  • Travix是如何部署应用程序到Kubernetes上的
  • Yii源码解读-服务定位器(Service Locator)
  • 动态魔术使用DBMS_SQL
  • 对象管理器(defineProperty)学习笔记
  • 分布式熔断降级平台aegis
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 前端技术周刊 2019-02-11 Serverless
  • 前端相关框架总和
  • 区块链共识机制优缺点对比都是什么
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 项目实战-Api的解决方案
  • 延迟脚本的方式
  • 用Python写一份独特的元宵节祝福
  • 《天龙八部3D》Unity技术方案揭秘
  • #Linux(make工具和makefile文件以及makefile语法)
  • $NOIp2018$劝退记
  • (2)STL算法之元素计数
  • (rabbitmq的高级特性)消息可靠性
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (附源码)计算机毕业设计大学生兼职系统
  • (四)Linux Shell编程——输入输出重定向
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .Net IOC框架入门之一 Unity