Codeforces 1009G Allowed Letters FMT,二分图,二分图匹配,霍尔定理
原文链接https://www.cnblogs.com/zhouzhendong/p/CF1009G.html
题目传送门 - CF1009G
题意
给定一个长度为 $n$ 的字符串 $s$ 。并给定 $m$ 条限制,第 $i$ 条限制声明了第 $i$ 个位置的字符可以取的值。如果没有声明表示可以任意取值。
求一个字符串 $s$ 的排列,在满足 $m$ 条限制的同时,使得字典序最小。如果不存在满足限制条件的字符串,则输出 $-1$。
$n,m\leq 10^5$,字符集 $ = \{'a','b','c','d','e','f'\}$
题解
我们先考虑如何判定是否有解。
统计一下原字符串中每一个字母的出现次数。容易建出一个二分图,左侧的 $n$ 个节点为字符串的每一个位置,右侧的 $n$ 个节点为 $n$ 个字母,这 $n$ 个字母中每种字符的出现次数等于原字符串中对应字符的出现次数;对于左侧的每一个点,即字符串的每一个位置,向它所能填的字母连上边(补充一下:这样做,右侧相同字母节点其实是等价的,他们的边集是相同的,这里设由字符 $c$ 组成的等价类为 $S_c$ )。那么,只需要求出最大匹配数,就可以知道最多有多少个位置可以放正确的字母。
然而,我们是否可以得到一种较快的判定是否有完美匹配的做法呢?显然有啊。
霍尔定理:设一个二分图 G 中的两部分顶点组成的集合分别为 X, Y ,则 G 中有一组无公共点的边,一端恰好为组成X的点的充分必要条件是:X中的任意k个点至少与Y中的k个点相邻。
根据霍尔定理,得到:
命题1 :一个满足 |X| = |Y| 的二分图,存在完美匹配的充分必要条件是:在 X 中任选 k 个点,至少与 Y 中 k 个点相邻。
回到原图的判定。我们令左侧点集为 $Y$ ,右侧点集为 $X$ ,则我们只需要证明:在 $X$ 中任选 $k$ 个点,至少与 $Y$ 中 $k$ 个点相邻。但是我们显然不能去枚举子集。注意之前提到的: $X$ 中有等价的点,我们接下来称一组等价的点为一个等价类。考虑在 $X$ 中选择一些等价类,得到等价类集合 $E$,假设这些等价类包含了 $k$ 个节点,如果 $Y$ 中只存在小于 $k$ 个点与之相邻,那么根据命题1,原图不存在完美匹配;否则,令 $f(E)$ 表示等价类集合 $E$ 中的节点在 $Y$ 中的相邻点个数,对于每一个等价类 $S_c\in E,c\in\{'a','b','c','d','e','f'\}$ ,$\forall S_c\subseteq P_c,P_c\neq \emptyset $,则如果令 $Q = \{P_c|S_c\in E\}$ 必然存在 $f(E)=f(P)$,从而 $\sum_\limits{P_c\in Q}|P_c|\leq \sum _\limits{S_c\in E}|S_c|\leq f(E)=f(P)$ ,故我们只需要检验所有等价类集合就可以了。
由于字符集非常的小,而不同的等价类数是不大于字符集大小的,所以单次检验的运算次数为 $2^6$ 。我们发现这个速度非常快!所以我们可以考虑预处理每一个字符集的在每一个后缀限制中出现的非空子集个数,用到 FMT 来快速处理(不用会慢一点)。然后贪心的从字符串开头到结尾逐位按照字典序试着放字符,并判断快速判断是否合法即可。
设字符集大小为 $x$ ,则时间复杂度为 $O(nx\cdot 2^x)$ 。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=100005;
int read(){
int x=0;
char ch=getchar();
while (!isdigit(ch))
ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+ch-48,ch=getchar();
return x;
}
char s[N];
int n,v[N],suf[N][64],tot[64],sum[64],Log[64];
void getv(){
int m=read();
memset(v,0,sizeof v);
while (m--){
int id=read();
char s[10];
scanf("%s",s+1);
int len=strlen(s+1);
for (int i=1;i<=len;i++)
v[id]|=1<<(s[i]-'a');
}
for (int i=1;i<=n;i++)
if (v[i]==0)
v[i]=63;
}
bool check(int p){
sum[0]=0;
for (int i=1;i<64;i++){
sum[i]=sum[i^(i&-i)]+tot[i&-i];
if (sum[i]<suf[p][i])
return 0;
}
return 1;
}
int main(){
Log[1]=0;
for (int i=2;i<64;i++)
Log[i]=Log[i>>1]+1;
gets(s+1);
n=strlen(s+1);
getv();
memset(tot,0,sizeof tot);
for (int i=1;i<=n;i++)
tot[1<<(s[i]-'a')]++;
memset(suf,0,sizeof suf);
for (int i=n;i>=1;i--){
for (int j=0;j<64;j++)
suf[i][j]=suf[i+1][j];
suf[i][v[i]]++;
}
for (int id=1;id<=n;id++)
for (int i=1;i<64;i<<=1)
for (int j=0;j<64;j++)
if (j&i)
suf[id][j]+=suf[id][j^i];
if (!check(1)){
printf("Impossible");
return 0;
}
for (int i=1;i<=n;i++)
for (int j=v[i],k=j&-j;j;j^=k,k=j&-j){
tot[k]--;
if (check(i+1)){
putchar('a'+Log[k]);
break;
}
tot[k]++;
}
return 0;
}
Codeforces 1009G Allowed Letters FMT,二分图,二分图匹配,霍尔定理的更多相关文章
- Codeforces 1009G Allowed Letters 最大流转最小割 sosdp
Allowed Letters 最直观的想法是贪心取, 然后网络流取check可不可行, 然后T了. 想到最大流可以等于最小割, 那么我们状压枚举字符代表的6个点连向汇点是否断掉, 然后再枚举64个本 ...
- Codeforces 611H - New Year and Forgotten Tree(二分图多重匹配)
Codeforces 题目传送门 & 洛谷题目传送门 首先我们将所有十进制下位数相同的点看作一种颜色,这样题目转化为,给定 \(m\le 6\) 种颜色.每种颜色的点的个数 \(b_i\) 以 ...
- POJ2289 Jamie's Contact Groups(二分图多重匹配)
Jamie's Contact Groups Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 7721 Accepted: ...
- poj 2289 Jamie's Contact Groups【二分+最大流】【二分图多重匹配问题】
题目链接:http://poj.org/problem?id=2289 Jamie's Contact Groups Time Limit: 7000MS Memory Limit: 65536K ...
- HDU 1669 二分图多重匹配+二分
Jamie's Contact Groups Time Limit: 15000/7000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/ ...
- POJ2289 Jamie's Contact Groups —— 二分图多重匹配/最大流 + 二分
题目链接:https://vjudge.net/problem/POJ-2289 Jamie's Contact Groups Time Limit: 7000MS Memory Limit: 6 ...
- hihoCoder 1393 网络流三·二分图多重匹配(Dinic求二分图最大多重匹配)
#1393 : 网络流三·二分图多重匹配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小H ...
- 【POJ 1698】Alice's Chance(二分图多重匹配)
http://poj.org/problem?id=1698 电影和日子匹配,电影可以匹配多个日子. 最多有maxw*7个日子. 二分图多重匹配完,检查一下是否每个电影都匹配了要求的日子那么多. #i ...
- 稳定的奶牛分配 && 二分图多重匹配+二分答案
题意: 农夫约翰有N(1<=N<=1000)只奶牛,每只奶牛住在B(1<=B<=20)个奶牛棚中的一个.当然,奶牛棚的容量有限.有些奶牛对它现在住的奶牛棚很满意,有些就不太满意 ...
随机推荐
- 51nod--1242 斐波那契数列第N项 (矩阵乘法优化)
题目: 1242 斐波那契数列的第N项 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 斐波那契数列的定义如下: F(0) = 0 F(1) = 1 F(n) ...
- SSH localhost免密不成功 + 集群状态显示Configured Capacity: 0 (0 KB)
前一天运行hadoop一切安好,今天重新运行出现BUG.下面对遇到的bug.产生原因以及解决方法进行一下简单总结记录. [bug1]用ssh localhost免密登录时提示要输入密码. 原因分析:之 ...
- 【原创】大数据基础之Hadoop(2)hdfs和yarn最简绿色部署
环境:3结点集群 192.168.0.1192.168.0.2192.168.0.3 1 配置root用户服务期间免密登录 参考:https://www.cnblogs.com/barneywill/ ...
- mysql定时任务,每天的零点执行一个存储过程
1 前言 利用navicat工具来写存储过程及定时执行,此文章是按照自身经验总结的,仅作为记录使用. 2 步骤 2.1 新建过程 2.2 在函数体写你需要执行的代码 CREATE DEFINER=`r ...
- Android 设备的CPU类型(通常称为”ABIs”)
armeabiv-v7a: 第7代及以上的 ARM 处理器.2011年15月以后的生产的大部分Android设备都使用它. arm64-v8a: 第8代.64位ARM处理器,很少设备,三星 Galax ...
- html<meta>标签
1. 定义说明 <meta>提供与页面有关的元数据,元数据是对数据的描述 <meta>总是位于<head></head>中 <meta>定义 ...
- 【转】光盘和U盘安装win7和ubuntu14.04全步骤
详细步骤见原链接:http://brianway.github.io/2016/01/18/linux-win7-ubuntu-setup-by-USBandCD/ 安装Linux步骤 1. 在win ...
- Confluence 6 "Duplicate Key" 相关问题解决
如果你遇到了下面的错误信息,例如: could not insert: [bucket.user.propertyset.BucketPropertySetItem#bucket.user.prope ...
- linux目录详解
网卡的配置文件目录 /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 ...
- python 之 列表与字典
1.4 列表与字典 列表与字典,这两种类型,都是各种类型的集合,以列表为例,如果列表中包含列表,就形成嵌套. 这两种类型几乎是所有python脚本的主要工作组件 . 这种结构信息是可变的可修改的.不像 ...