JZOJ 3281. 【GDOI2013】字母连接
\(\text{Solution}\)
一眼不会,限制有点多。。。
那就网络流
发下确实是很简单的建图
枚举起点集合
拆点后就很好满足限制了
\(\text{Code}\)
#include <cstdio>
#include <iostream>
#include <cstring>
#define RE register
#define IN inline
using namespace std;
const int N = 1005, INF = 2147483647;
int n, m, S, T, num, p1, p2, tot, ans;
int dis[N], h[N], vis[N], pre[N], edge[N], flow[N], a[25][25], d[N], buc[N], Q[N];
int fx[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
char str[20];
struct node{int to, nxt, w, f;}e[N * 10];
IN void add(int u, int v, int w, int f)
{
e[++tot] = node{v, h[u], w, f}, h[u] = tot;
e[++tot] = node{u, h[v], 0, -f}, h[v] = tot;
}
IN int Isin(int x, int y){return (x > 0 && x <= n && y > 0 && y <= m && a[x][y] != 101);}
IN int getid(int x, int y){return (x - 1) * m + y;}
IN int spfa()
{
for(RE int i = S; i <= T; i++) vis[i] = 0, dis[i] = flow[i] = INF;
int head = 0, tail = 1;
d[1] = S, vis[S] = 1, dis[S] = 0, pre[T] = -1;
while (head < tail)
{
int now = d[++head];
vis[now] = 0;
for(RE int i = h[now]; i; i = e[i].nxt)
if (dis[e[i].to] > dis[now] + e[i].f && e[i].w)
{
dis[e[i].to] = dis[now] + e[i].f, flow[e[i].to] = min(flow[now], e[i].w), pre[e[i].to] = now, edge[e[i].to] = i;
if (!vis[e[i].to]) vis[e[i].to] = 1, d[++tail] = e[i].to;
}
}
return pre[T] != -1;
}
IN int MCMF()
{
int now, Maxflow = 0, Mincost = 0;
while (spfa())
{
Maxflow += flow[T], Mincost += dis[T] * flow[T], now = T;
while (now != S) e[edge[now]].w -= flow[T], e[edge[now] ^ 1].w += flow[T], now = pre[now];
}
if (Maxflow != num / 2) return INF;
return Mincost;
}
IN void solve()
{
memset(h, 0, sizeof h), tot = 1, T = n * m * 2 + 1;
for(RE int i = 1; i <= n; i++)
for(RE int j = 1; j <= m; j++)
if (a[i][j] != 101)
{
if (a[i][j] == 100) add(getid(i, j), getid(i, j) + n * m, 1, 1);
else add(getid(i, j), getid(i, j) + n * m, 1, 0);
for(RE int k = 0; k < 4; k++)
{
int x = i + fx[k][0], y = j + fx[k][1];
if (Isin(x, y)) add(getid(i, j) + n * m, getid(x, y), 1, 0);
}
}
for(RE int i = 1; i <= num; i++)
if (buc[Q[i]]) add(S, Q[i], 1, 0);
else add(Q[i] + n * m, T, 1, 0);
ans = min(ans, MCMF());
}
void dfs(int x, int s)
{
if (s > num / 2) return;
if (x > num)
{
if (s == num / 2 && ((!p1 && !p2) || (buc[p1] && buc[p2]))) solve();
return;
}
buc[Q[x]] = 1, dfs(x + 1, s + 1), buc[Q[x]] = 0, dfs(x + 1, s);
}
int main()
{
int q; scanf("%d", &q);
for(; q; --q)
{
memset(buc, 0, sizeof buc), num = p1 = p2 = 0, ans = INF, scanf("%d%d", &n, &m);
for(RE int i = 1; i <= n; i++)
{
scanf("%s", str + 1);
for(RE int j = 1, id; j <= m; j++)
if (str[j] == '.') a[i][j] = 100;
else if (str[j] == '#') a[i][j] = 101;
else
{
a[i][j] = str[j] - 'A' + 1, id = getid(i, j), Q[++num] = id;
if (buc[a[i][j]]) p1 = buc[a[i][j]], p2 = id;
buc[a[i][j]] = id;
}
}
memset(buc, 0, sizeof buc), dfs(1, 0), printf("%d\n", (ans == INF ? -1 : ans));
}
}
JZOJ 3281. 【GDOI2013】字母连接的更多相关文章
- LODOP字体不识别 英文字母连起来 引号不正常
打印超文本的时候,有时候会发现html中设置的css样式显示不正常,字体根本不是设置的字体,这种情况有可能是:1.该操作系统没有安装自己指定的那种字体,那么没有安装自然就不能显示设置的字体.2.该操作 ...
- Leetcode17--->Letter Combinations of a Phone Number(电话号码对应的字母的组合)
题目: 给定一个数字字符串,返回数字所能代表的所有字母组合: 举例: Input:Digit string "23" Output: ["ad", " ...
- EasyPR--开发详解(4)形态学操作、尺寸验证、旋转等操作
在上一篇深度分析与调优讨论中,我们介绍了高斯模糊,灰度化和Sobel算子.在本文中,会分析剩余的定位步骤. 根据前文的内容,车牌定位的功能还剩下如下的步骤,见下图中未涂灰的部分. 图1 车牌定位步骤 ...
- pythonchallenge(二)
PythonChallenge_2 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou,密码shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux ...
- Lua中的捕获
Lua中的捕获 捕获 捕获是这样一种机制:可以使用模式串的一部分匹配目标串的一部分.将你想捕获的模式用圆括号括起来,就指定了一个捕获.在string.find使用捕获的时候,函数会返回捕获的值作为 ...
- bzoj2537: [neerc2007]Language Recognition
Description DFA(确定性有限状态自动机)是一个有向图,顶点称为状态,边称为转移.每个转移用一个字母标记.对于每个状态s和每个转移l,至多有一个转移从s出发且标记为l.DFA有一个初始状态 ...
- 惊艳的随机化方法 -World Search (homework-04)
homeword04-word search 0. 摘要 本次作业,要求完成一个word search的程序,具体要求是: 输入:一个包含20-60个单词的文件,各单词不大于20个字母,无空格. 输出 ...
- 辛星浅谈PHP的混乱的编码风格
我们都知道.各种编程语言都有自己的风格,即使是像C和C++那样一脉相承的语言(C++本意全然兼容C的语法).编程风格上还是有些区别.比方非常典型的就是C++风格的单行凝视和C风格的多行凝视. 而尽管J ...
- Vim文本编辑器 指令簿(二)
常常处理文本以及常常须要写代码的人,都会有自己比較常常使用的编辑器,本人喜欢用Vim.理由就是Vim编辑器灵活,而且能够达到纯键盘操作,使用纯熟情况下,根本不须要鼠标操作.听起来是不是非常酷的?只是别 ...
- EasyPR--开发详解
我正在做一个开源的中文车牌识别系统,Git地址为:https://github.com/liuruoze/EasyPR. 我给它取的名字为EasyPR,也就是Easy to do Plate Reco ...
随机推荐
- 解决redmi airdots 2右耳充不进电,灯不亮
解决方案 在放入充电盒并插入数据线充电状态下,长按按钮
- Java反射与安全问题
1.Java反射机制 Java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的 ...
- shell编写循环检查脚本
背景:如下脚本实现当微服务重启后,检查微服务的启动端口正常,可通过轮询的方式来实现所需要用到配置文件config.properties信息如下: onlineService:8001 algorthS ...
- 【Spark】Day03-Spark SQL:DataFrame、DataSet、sql编程与转换、项目实战(区域热门商品)
一.概述 1.介绍 将Spark SQL转换成RDD,然后提交到集群执行[对比hive] 提供2个编程抽象:DataFrame&DataSet 可以使用SQL和DatasetAPI与Spark ...
- Day33:String类及其常用方法详解
String类 1.1 String类概述 Java中字符串属于对象,String类用于创建和操作字符串. 最简单的字符串创建:直接通过String创建 String str="工地佬&qu ...
- 解析【.mdb】文件
有一些项目用的是微软的access软件,这里面存放数据用的是mdb结尾的文件 有的时候,客户想开发一个新的系统,但是数据需要从这些文件中获取,因此得解析这些文件,来提取数据 一.解析时用到的依赖 1. ...
- 【JVM故障问题排查心得】「内存诊断系列」Docker容器经常被kill掉,k8s中该节点的pod也被驱赶,怎么分析?
背景介绍 最近的docker容器经常被kill掉,k8s中该节点的pod也被驱赶. 我有一个在主机中运行的Docker容器(也有在同一主机中运行的其他容器).该Docker容器中的应用程序将会计算数据 ...
- M.2 SSD固态硬盘上安装windows问题
近来M2硬盘大降价,笔记就趁便宜买了一个2T的M.2固态硬盘,插在笔记本上,接下来安装win11,本想以前安装多次,也是老手了,没想到遇到很多问题,一度陷入僵局,不过最终还是安装成功了,下面记录下安装 ...
- [深度学习] CCPD车牌数据集介绍
CCPD是一个大型的.多样化的.经过仔细标注的中国城市车牌开源数据集.CCPD数据集主要分为CCPD2019数据集和CCPD2020(CCPD-Green)数据集.CCPD2019数据集车牌类型仅有普 ...
- org.apache.catalina.startup.HostConfig.deployWAR Error deploying web application archive
昨天23点给一个老项目改完打包发布到云服务器后报错,Tomcat9 启动不了,白折腾了我几个小时. 这错误以前遇到过,由于太过久远已经忘记,特此记录 错误日志 22-Dec-2021 23:52:18 ...