1194: [HNOI2006]潘多拉的盒子

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 464  Solved: 221
[Submit][Status][Discuss]

Description

Input

第一行是一个正整数S,表示宝盒上咒语机的个数,(1≤S≤50)。文件以下分为S块,每一块描述一个咒语机,按照咒语机0,咒语机1„„咒语机S-1的顺序描述。每一块的格式如下。 一块的第一行有两个正整数n,m。分别表示该咒语机中元件的个数、咒语源输出元的个数(1≤m≤n≤50)。 接下来一行有m个数,表示m个咒语源输出元的标号(都在0到n-1之间)。接下来有n行,每一行两个数。第i行(0≤i≤n-1)的两个数表示pi,0和pi,1(当然,都在0到n-1之间)。

Output

第一行有一个正整数t,表示最长升级序列的长度。

Sample Input

4
1 1
0
0 0
2 1
0
1 1
0 0
3 1
0
1 1
2 2
0 0
4 1
0
1 1
2 2
3 3
0 0

Sample Output

3

HINT

 

Source

分析:

  思路比较简单:对于每对i,j,如果满足i能产生的所有字符串j都能产生,则建边,跑最长路。
但是图可能不是DAG,所以要先预处理缩点,然后再做。

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N=;
struct data{int danger[N],lc[N],rc[N];}T[N];
struct edge{int v,next;}e[N*N*],e2[N*N*];
int S,ans,a,b,tot,head[N],tot2,head2[N];bool flag,vis[N][N];
int dfs_cnt,scc_cnt,top,dfn[N],low[N],num[N],sccno[N],stack[N],dp[N];
void add(int x,int y){
e[++tot].v=y;e[tot].next=head[x];head[x]=tot;
}
void add2(int x,int y){
e2[++tot2].v=y;e2[tot2].next=head2[x];head2[x]=tot2;
}
void dfs_contain(int x,int y){
if(vis[x][y]||flag) return ;
vis[x][y]=;
if(T[b].danger[y]&&!T[a].danger[x]){flag=;return ;}
dfs_contain(T[a].lc[x],T[b].lc[y]);
dfs_contain(T[a].rc[x],T[b].rc[y]);
}
bool check(int x,int y){
flag=;a=x;b=y;
memset(vis,,sizeof vis);
dfs_contain(,);
return !flag;
}
void tarjan(int u){
dfn[u]=low[u]=++dfs_cnt;
stack[++top]=u;
for(int i=head[u];i;i=e[i].next){
int v=e[i].v;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],dfn[v]);
}
else if(!sccno[v]){
low[u]=min(low[u],low[v]);
}
}
if(low[u]==dfn[u]){
scc_cnt++;
for(int x;;){
x=stack[top--];
sccno[x]=scc_cnt;
num[scc_cnt]++;//WA*2
if(x==u) break;
}
}
}
int get_cnt(int x){
if(dp[x]) return dp[x];
int maxn=num[x];//WA*1
for(int i=head2[x];i;i=e2[i].next){
maxn=max(maxn,dp[e2[i].v]+num[x]);
}
return dp[x]=maxn;
}
int main(){
scanf("%d",&S);
for(int k=,n,m,x,y;k<=S;k++){
scanf("%d%d",&n,&m);
while(m--) scanf("%d",&x),T[k].danger[x+]=;
for(int i=;i<=n;i++){
scanf("%d%d",&x,&y);
T[k].lc[i]=x+;
T[k].rc[i]=y+;
}
}
for(int i=;i<=S;i++){
for(int j=;j<=S;j++){
if(i==j) continue;
if(check(i,j)) add(i,j);
}
}
for(int i=;i<=S;i++) if(!dfn[i]) tarjan(i);
for(int i=;i<=S;i++){
for(int j=head[i];j;j=e[j].next){
if(sccno[i]!=sccno[e[j].v]) add2(sccno[i],sccno[e[j].v]);
}
}
for(int i=;i<=scc_cnt;i++) ans=max(ans,get_cnt(i));
printf("%d\n",ans);
return ;
}

1194: [HNOI2006]潘多拉的盒子的更多相关文章

  1. 图论(Tarjan缩点):BZOJ 1194: [HNOI2006]潘多拉的盒子

    1194: [HNOI2006]潘多拉的盒子 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 344  Solved: 181[Submit][Stat ...

  2. BZOJ 1194: [HNOI2006]潘多拉的盒子( BFS + tarjan + dp )

    O(S²)枚举2个诅咒机, 然后O(n²)BFS去判断. 构成一个有向图, tarjan缩点, 然后就是求DAG的最长路.. ------------------------------------- ...

  3. 1194: [HNOI2006]潘多拉的盒子 - BZOJ

    Description  Input 第一行是一个正整数S,表示宝盒上咒语机的个数,(1≤S≤50).文件以下分为S块,每一块描述一个咒语机,按照咒语机0,咒语机1„„咒语机S-1的顺序描述.每一块的 ...

  4. BZOJ 1194: [HNOI2006]潘多拉的盒子 [DP DFA]

    传送门 题意: s个DFA,选出尽量多的自动机a0, a1, a2, . . . , at,使得a1包含a0.a2包 含a1,以此类推.s ≤ 50. DFA的字符集为{0,1},有的节点是输出源,节 ...

  5. BZOJ 1194 [HNOI2006]潘多拉的盒子 (图论+拓扑排序+tarjan)

    题面:洛谷传送门 BZOJ传送门 标签里三个算法全都是提高组的,然而..这是一道神题 我们把这道题分为两个部分解决 1.找出所有咒语机两两之间的包含关系 2.求出咒语机的最长上升序列 我们假设咒语机$ ...

  6. BZOJ1194: [HNOI2006]潘多拉的盒子(tarjan)

    Description 传说中,有个神奇的潘多拉宝盒.如果谁能打开,便可以拥有幸福.财富.爱情.可是直到真的打开,才发现与之 相随的还有灾难.不幸.其实,在潘多拉制造这个宝盒的时候,设置了一些咒语来封 ...

  7. 【bzoj1194】 HNOI2006—潘多拉的盒子

    http://www.lydsy.com/JudgeOnline/problem.php?id=1194 (题目链接) 题意 给出S个自动机,如果一个自动机u的所有状态是另一个自动机v的状态的子集,那 ...

  8. 【强连通分量】Bzoj1194 HNOI2006 潘多拉的盒子

    Description Sulotion 首先要对每对咒语机建图,判断机器a是否能生成所有机器b生成的 如果跑一个相同的串,最后结束的点b可输出a不可输出,判断就为否 大概就用这种思路,f[x][y] ...

  9. HNOI2006 潘多拉的盒子

    题目描述 题解: 题目的描述比较长,理解起来也有一定难度.仔细读题后我们发现整个任务可以分成两个部分:找出咒语机之间所有的升级关系.求最长升级序列. 1. 求升级关系: 容易看出,咒语机i可以抽象成一 ...

随机推荐

  1. hdu 1492(约数的个数)

    The number of divisors(约数) about Humble Numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Lim ...

  2. 怎样录制简单GIF动图

    看到视频里的精彩画面,想用动图的形式保存下来,应该如何录制呢,今天就介绍一款小巧实用,操作简单的软件,GifCam 2.0 汉化绿色版.相比其它的录制软件,它是免费无水印又可以在线录制的. 本来学习一 ...

  3. 各语言最原始数据库访问组件封装DBHelper

    源码:https://github.com/easonjim/DBHelper bug提交:https://github.com/easonjim/DBHelper/issues 每个语言放在不同的分 ...

  4. php正则表达式取子字符串及替换

    最近在学习如何用php编写cms,想把文章中的第一个图片提取出来当做缩略图显示到前面,想到的方法就是把文章内容作为一个大字符串,然后用正则表达式找出匹配出第一次出现<img src=" ...

  5. mac 配置pylucene

    1 . 安装python 2  安装ant 3  下载pylucene 4  cd jcc , vim setup.py , 查看java路径和python路径是否正确 5 python setup. ...

  6. MQ学习-RabbitMQ, ActiveMQ, Kafka等

    之前学习过RabbitMQ,并且还安装过.安装记录的文章如下: Erlang:http://www.cnblogs.com/charlesblc/p/5512380.html RabbitMQ:htt ...

  7. 对ps4 cmask fmask的理解

    这俩都是绑在corlor target上8x8的格子 cmask 做fastclear 这个比较好理解,8x8来表示这个格子是否clear fmask msaa用 provided to suppor ...

  8. 【前端阅读】——《JavaScript应用开发技术详解指南》摘记&思维导图

    读这本书,我主要关注三个部分:JavaScript内置函数,程序调试以及Ajax基础.由于多是介绍基本概念,所以,采用思维导图的方式,做了一个梳理,以下就是精简的主要内容. 注:转载请注明出处

  9. zerglurker的C语言教程007——代码运行的顺序

    软件开发中.代码有三种基本运行顺序: 顺序运行 代码从入口開始一条一条运行.直到返回或者结束 循环运行 在设定条件后,代码反复运行某一个或多个部分,直到达到某些条件后终止 条件运行 代码会先推断某些条 ...

  10. hdu1394 Minimum Inversion Number(最小逆序数)

    Minimum Inversion Number Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/O ...