P7086 题解
考虑把每个字符串的前 \(k\) 位和后 \(k\) 位看成点,字符串看成边,那么一个字符串前缀后缀至少有一个是相似群体的前缀后缀,看成这条边的两个端点至少有一个被选中。
那么这就变成了一个最小点覆盖问题。
考虑匈牙利算法算出答案,然后考虑如何构造答案。
考虑右边没有被匹配的点,选中这些点向左边连的点,因此这个点本身就不用被选中,考虑左边刚刚被选中的点,它们在右边匹配的点就不用选了,那么它们在右边匹配的点就进入右边没有被匹配的点相同的流程,如此递归下去,那么左边便利到的点就会被选中,右边被遍历到的点就不会被选中。
如此便可以构造出选中的点,然后再分配字符串到集合即可。
#include<bits/stdc++.h>
#define int unsigned long long
using namespace std;
const int maxn = 1e6+114;
const int base = 1145141;
int vis[maxn],match[maxn];
vector<int> edge[maxn],fedge[maxn];
map<int,int> road[2][maxn];
int ans;
int fm[maxn];
bool hungary(int u){
for(int v:edge[u]){
if(vis[v]==1) continue;
vis[v]=1;
if(match[v]==0||hungary(match[v])==true){
match[v]=u;
fm[u]=v;
return true;
}
}
return false;
}
int pre[maxn],suf[maxn];
int n,k,cnt;
map<int,int> f;
map<int,int> p[2];
vector<int> chifan[2];
int use[maxn][2];
vector<int> answer[2];
map<int,int> pos[2];
int op[maxn][2];
vector<int> OUT[maxn][2];
void dfs(int u,int type){
if(op[u][type]==1) return ;
op[u][type]=1;
if(type==0){
dfs(fm[u],1);
}
else{
for(int nxt:fedge[u]){
if(nxt!=match[u]){
dfs(nxt,0);
}
}
}
}
signed main(){
cin>>n>>k;
for(int i=1;i<=n;i++){
string s;
cin>>s;
for(int j=0;j<k;j++){
pre[i]=pre[i]*base+s[j];
}
for(int j=s.size()-1;j>=s.size()-k&&j<s.size();j--){
suf[i]=suf[i]*base+s[j];
}
if(f[pre[i]]==0){
f[pre[i]]=++cnt;
}
if(p[0][f[pre[i]]]==0)
chifan[0].push_back(f[pre[i]]),p[0][f[pre[i]]]=1;
if(f[suf[i]]==0){
f[suf[i]]=++cnt;
}
if(p[1][f[suf[i]]]==0)
chifan[1].push_back(f[suf[i]]),p[1][f[suf[i]]]=1;
edge[f[pre[i]]].push_back(f[suf[i]]),fedge[f[suf[i]]].push_back(f[pre[i]]);
}
for(int i:chifan[0]){
memset(vis,0,sizeof(vis));
if(hungary(i)==true) ans++;
}
for(int i:chifan[1]){
if(match[i]==0){
dfs(i,1);
}
}
for(int i=1;i<=n;i++){
if(op[f[pre[i]]][0]==1){
OUT[f[pre[i]]][0].push_back(i);
}
else if(op[f[suf[i]]][1]==0){
OUT[f[suf[i]]][1].push_back(i);
}
}
cout<<ans<<'\n';
for(int i:chifan[0]){
if(op[i][0]==1){
cout<<OUT[i][0].size()<<' ';
for(int j:OUT[i][0]) cout<<j<<' ';
cout<<'\n';
}
}
for(int i:chifan[1]){
if(op[i][1]==0){
cout<<OUT[i][1].size()<<' ';
for(int j:OUT[i][1]) cout<<j<<' ';
cout<<'\n';
}
}
return 0;
}
P7086 题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
- JSOI2016R3 瞎BB题解
题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...
随机推荐
- NASM中的ALIGN ALIGNB SECTALIGN
ALIGN与ALIGNB NASM中的ALIGN与ALIGNB是用来字节对齐的,它们接收2个参数,第一个参数是必须的,表示对齐的字节数(必须是2的幂),第二个参数是可选的,表示为了对齐而进行填充的内容 ...
- HH的项链——题解
题目描述 直接求解会导致不同贝壳在上个区间算过但这个区间没标记的情况,所以在求解时要把上个区间的标记转移到这个区间 转移前先右边界由小到大排序,然后转移上个右边界到这个右边界的标记,同时记录上个标记出 ...
- 使用 Docker 部署 WebTop 运行 Linux 系统
1)项目介绍 GitHub:https://github.com/linuxserver/docker-webtop WebTop 它是一个基于 Linux ( Ubuntu 和 Alpine 两种版 ...
- 生物医学顶刊论文(JBHI-2024):TransFOL:药物相互作用中复杂关系推理的逻辑查询模型
(2024.5.17)JBHI-TransFOL:药物相互作用中复杂关系推理的逻辑查询模型 论文题目:TransFOL: A Logical Query Model for Complex Relat ...
- 异构数据源同步之数据同步 → datax 改造,有点意思
开心一刻 去年在抖音里谈了个少妇,骗了我 9 万 后来我发现了,她怕我报警 她把她表妹介绍给我 然后她表妹又骗了我 7 万 DataX DataX 是什么,有什么用,怎么用 不做介绍,大家自行去官网( ...
- C# Datagridview combox列 初始化颜色
DataGridView 初始化完成后,在combox里显示颜色,如这样: DataGridView 注册 cellPainting事件: private void m_dataGridView_Ce ...
- P1683 入门
传送锚点:https://www.luogu.com.cn/problem/P1683 题目描述 不是任何人都可以进入桃花岛的,黄药师最讨厌像郭靖一样呆头呆脑的人.所以,他在桃花岛的唯一入口处修了一条 ...
- [快速阅读六] 统计内存数据中二进制1的个数(SSE指令集优化版).
关于这个问题,网络上讨论的很多,可以找到大量的资料,我觉得就就是下面这一篇讲的最好,也非常的全面: 统计无符号整数二进制中 1 的个数(Hamming Weight) 在指令集不参与 ...
- 【Java面试题-基础知识01】Java数据类型四连问?
一.Java中的基础数据类型有哪些? Java中的基本数据类型包括: 1. byte:8位有符号整数,范围为-128到127.2. short:16位有符号整数,范围为-32768到32767.3. ...
- 一文搞懂 ARM 64 系列: 寄存器
ARM 64中包含多种寄存器,下面介绍一些常见的寄存器. 1 通用寄存器 ARM 64包含31个64bit寄存器,记为X0~X30. 每一个通用寄存器,它的低32bit都可以被访问,记为W0~W30. ...