BZOJ 1194: [HNOI2006]潘多拉的盒子 [DP DFA]
题意:
s个DFA,选出尽量多的自动机a0, a1, a2, . . . , at,使得a1包含a0、a2包 含a1,以此类推。s ≤ 50。
DFA的字符集为{0,1},有的节点是输出源,节点数n ≤ 50。
判断出包含关系后就是裸的最长路,求$SCC$后$DP$就好了
重点在判断包含:
$n$实在太小了,我们直接枚举所有的自动机,然后两个同时从起点开始$bfs$所有情况看看是否在某个状态一个有输出另一个没有
复杂度$O(n^4)$
注意:
$Candy?$这个沙茶$bfs$没有判断$(0,0)$状态是否一个输出一个不输出$WA$了好久,并且他还有一次求$SCC$没有枚举所有点
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int s,n,m;
struct DFA{
int n,m,p[N][],out[N];
}a[N];
struct edge{
int v,ne;
}e[N*N<<],e2[N*N<<];
int h[N],cnt,h2[N],cnt2;
inline void ins(int u,int v){//printf("ins %d %d %d\n",cnt,u,v);
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
}
inline void ins2(int u,int v){//printf("ins2 %d %d\n",u,v);
edge *e=e2;int *h=h2,&cnt=cnt2;
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
}
struct node{
int x,y;
node(int a=,int b=):x(a),y(b){}
}q[N*N];
int head,tail;
bool vis[N][N];
void bfs(DFA &a,DFA &b,int i,int j){
int a_b=,b_a=;
memset(vis,,sizeof(vis));
head=tail=;
q[tail++]=node(,);vis[][]=;
while(head!=tail){
node u=q[head++];
int x=u.x , y=u.y;
if(a.out[x]&&!b.out[y]) b_a=;
if(!a.out[x]&&b.out[y]) a_b=;
if(a_b==&&b_a==) break;
for(int i=;i<=;i++){
int nx=a.p[x][i],ny=b.p[y][i];
if(!vis[nx][ny]){
vis[nx][ny]=;
q[tail++]=node(nx,ny);
}
}
}
if(a_b==) ins(i,j);
else if(b_a==) ins(j,i);
}
void buildGraph(){
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++) bfs(a[i],a[j],i,j);
} int dfn[N],dfc,low[N],scc,belong[N];
int st[N],top;
int val[N];
void dfs(int u){
dfn[u]=low[u]=++dfc;
st[++top]=u;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(!dfn[v]){
dfs(v);
low[u]=min(low[u],low[v]);
}else if(!belong[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
scc++;
while(true){
int x=st[top--];
belong[x]=scc;
val[scc]++;
if(x==u) break;
}
}
}
int f[N];
int dp(int u,int fa){
if(f[u]) return f[u];
for(int i=h2[u];i;i=e2[i].ne)
if(e2[i].v!=fa) f[u]=max(f[u],dp(e2[i].v,u));
return f[u]+=val[u];
}
int main(){
//freopen("in","r",stdin);
n=read();
for(int i=;i<=n;i++){
a[i].n=read();a[i].m=read();
for(int j=;j<=a[i].m;j++) a[i].out[read()]=;
for(int j=;j<a[i].n;j++) a[i].p[j][]=read(),a[i].p[j][]=read();
}
buildGraph();
for(int i=;i<=n;i++) if(!dfn[i]) dfs(i);
for(int u=;u<=n;u++)
for(int i=h[u];i;i=e[i].ne) if(belong[u]!=belong[e[i].v]) ins2(belong[u],belong[e[i].v]);
int ans=;
for(int i=;i<=scc;i++) ans=max(ans,dp(i,));
printf("%d\n",ans);
}
BZOJ 1194: [HNOI2006]潘多拉的盒子 [DP DFA]的更多相关文章
- 图论(Tarjan缩点):BZOJ 1194: [HNOI2006]潘多拉的盒子
1194: [HNOI2006]潘多拉的盒子 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 344 Solved: 181[Submit][Stat ...
- BZOJ 1194: [HNOI2006]潘多拉的盒子( BFS + tarjan + dp )
O(S²)枚举2个诅咒机, 然后O(n²)BFS去判断. 构成一个有向图, tarjan缩点, 然后就是求DAG的最长路.. ------------------------------------- ...
- BZOJ 1194 [HNOI2006]潘多拉的盒子 (图论+拓扑排序+tarjan)
题面:洛谷传送门 BZOJ传送门 标签里三个算法全都是提高组的,然而..这是一道神题 我们把这道题分为两个部分解决 1.找出所有咒语机两两之间的包含关系 2.求出咒语机的最长上升序列 我们假设咒语机$ ...
- 1194: [HNOI2006]潘多拉的盒子
1194: [HNOI2006]潘多拉的盒子 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 464 Solved: 221[Submit][Stat ...
- 1194: [HNOI2006]潘多拉的盒子 - BZOJ
Description Input 第一行是一个正整数S,表示宝盒上咒语机的个数,(1≤S≤50).文件以下分为S块,每一块描述一个咒语机,按照咒语机0,咒语机1„„咒语机S-1的顺序描述.每一块的 ...
- BZOJ1194: [HNOI2006]潘多拉的盒子(tarjan)
Description 传说中,有个神奇的潘多拉宝盒.如果谁能打开,便可以拥有幸福.财富.爱情.可是直到真的打开,才发现与之 相随的还有灾难.不幸.其实,在潘多拉制造这个宝盒的时候,设置了一些咒语来封 ...
- 【bzoj1194】 HNOI2006—潘多拉的盒子
http://www.lydsy.com/JudgeOnline/problem.php?id=1194 (题目链接) 题意 给出S个自动机,如果一个自动机u的所有状态是另一个自动机v的状态的子集,那 ...
- 【强连通分量】Bzoj1194 HNOI2006 潘多拉的盒子
Description Sulotion 首先要对每对咒语机建图,判断机器a是否能生成所有机器b生成的 如果跑一个相同的串,最后结束的点b可输出a不可输出,判断就为否 大概就用这种思路,f[x][y] ...
- HNOI2006 潘多拉的盒子
题目描述 题解: 题目的描述比较长,理解起来也有一定难度.仔细读题后我们发现整个任务可以分成两个部分:找出咒语机之间所有的升级关系.求最长升级序列. 1. 求升级关系: 容易看出,咒语机i可以抽象成一 ...
随机推荐
- Android扫码二维码、美女瀑布流、知乎网易音乐、动画源码等
Android精选源码 QRCode 扫描二维码.扫描条形码.相册获取图片后识别.生... 一个简洁好看的loading弹窗 Android用瀑布流展示美女图片源码 Android知乎阅读 ...
- node.js和express创建服务器
创建web服务器 一. 使用node.js创建服务器. 使用express创建http服务. 监控服务器的变化. 二. 初始化配置文件:npm init -y 使用typescript编写,导入nod ...
- jquery 和 mui 上拉加载
jquery: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <m ...
- Linux命令之远程下载命令:wget
转自:http://www.cnblogs.com/peida/archive/2013/03/18/2965369.html Linux系统中的wget是一个下载文件的工具,它用在命令行下.对于Li ...
- sql 中文转拼音首字母
http://blog.csdn.net/zhanglong_longlong/article/details/46772571 --可支持大字符集20000个汉字! create function ...
- LAMP与LNMP架构的区别及其具体的选择说明
LAMP==Linux+Apache+Mysql+PHP LNMP==Linux+Nginx+Mysql+PHP 以上两只架构是目前网站的主流架构 LAMP和LNMP最主要的区别在于: 一个使用的是A ...
- Android之MaterialDesign应用技术
PS:纵观现在大大小小软件的界面都变的比较漂亮,还有一些系统了,比如小米的MIUI,华为的EMUI等,虽然底层都是安卓,但他们的界面多多少少都会不同,谷歌对这个UI也是非常重视的,MaterialDe ...
- No grammar constraints (DTD or XML schema).....两种解决方法
方法一:常用方法 关闭XML验证 工具栏:windows => preferences => xml => xml files => validation => In ...
- MySQL数据引擎
InnoDB存储引擎 该引擎是MySQL数据库的默认事务型引擎,它被设计用来处理大量短期事务(绝大多数正常提交,很少回滚) InnoDB的数据存储在表空间中,表空间是由InnoDB管理的一个黑盒子,由 ...
- 二叉查找树C++实现
二分查找树特点: (1) 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2) 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值: (3) 任意节点的左.右子树 ...