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
/*
思路比较简单:对于每对i,j,如果满足i能产生的所有字符串j都能产生,则建边,跑最长路。
但是图可能不是DAG,所以要先预处理缩点,然后再做。
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 60
using namespace std;
int dfn[N],low[N],ins[N],sta[N],val[N],bl[N],indexx,num,top;
int vis[N][N],head[N],head2[N],dp[N],S,cnt,a,b,flag; struct Node{int danger[N],lc[N],rc[N];};Node T[N];
struct node{int to,pre;};node e[N*N*],e2[N*N*]; void add(int u,int v){
e[++cnt].to=v;
e[cnt].pre=head[u];
head[u]=cnt;
}
void add2(int u,int v){
e2[++cnt].to=v;
e2[cnt].pre=head2[u];
head2[u]=cnt;
}
void dfs(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(T[a].lc[x],T[b].lc[y]);
dfs(T[a].rc[x],T[b].rc[y]);
}
bool check(int i,int j){
flag=;a=i;b=j;
memset(vis,,sizeof(vis));
dfs(,);
if(!flag)return true;
return false;
}
void tarjan(int x){
dfn[x]=low[x]=++indexx;
sta[++top]=x;
ins[x]=;
for(int i=head[x];i;i=e[i].pre){
int v=e[i].to;
if(!dfn[v]){
tarjan(v);
low[x]=min(low[x],dfn[v]);
}
else if(ins[v])
low[x]=min(low[x],low[v]);
}
int u;
if(low[x]==dfn[x]){
++num;
do{
u=sta[top--];
val[num]++;
bl[u]=num;
ins[u]=;
}while(u!=x);
}
}
int dfs2(int x){
if(dp[x])return dp[x];
int maxn=val[x];
for(int i=head2[x];i;i=e2[i].pre)
maxn=max(maxn,dp[e2[i].to]+val[x]);
dp[x]=maxn;
return dp[x];
}
int main(){
scanf("%d",&S);
for(int s=;s<=S;s++){
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
int x;scanf("%d",&x);
T[s].danger[x+]=;
}
for(int i=;i<=n;i++){
int x,y;scanf("%d%d",&x,&y);
T[s].lc[i]=x+;T[s].rc[i]=y+;
}
}
for(int i=;i<=S;i++)
for(int j=;j<=S;j++)
if(i!=j&&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].pre)
if(bl[i]!=bl[e[j].to])add2(bl[i],bl[e[j].to]);
int ans=;
for(int i=;i<=num;i++)ans=max(ans,dfs2(i));
printf("%d",ans);
return ;
}

潘多拉的盒子(bzoj 1194)的更多相关文章

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

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

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

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

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

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

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

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

  5. 【BZOJ-1194】潘多拉的盒子 拓扑排序 + DP

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

  6. [BZOJ1194][HNOI2006][强连通分量Tarjan+dfs]潘多拉的盒子

    [BZOJ1194][HNOI2006]潘多拉的盒子 Input 第一行是一个正整数S,表示宝盒上咒语机的个数,(1≤S≤50).文件以下分为S块,每一块描述一个咒语机,按照咒语机0,咒语机1„„咒语 ...

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

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

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

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

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

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

随机推荐

  1. P2956 [USACO09OCT]机器人犁田The Robot Plow

    题目描述 Farmer John has purchased a new robotic plow in order to relieve him from the drudgery of plowi ...

  2. scrollTop、offsetTop、clientTop

    1.offsetTop: obj.offsetTop 指 obj 相对于版面或由 offsetParent 属性指定的父坐标的计算上侧位置. 2.clientTop: 这个返回的是元素周围边框的厚度, ...

  3. 如何正确理解关键字"with"与上下文管理器

    转自:https://foofish.net/with-and-context-manager.html 如果你有阅读源码的习惯,可能会看到一些优秀的代码经常出现带有 “with” 关键字的语句,它通 ...

  4. Smart SVN的使用

    最近项目使用了SVN,为管理代码起到了很好的作用!但是,对于很多初步使用着,还是非常不容易! 公司使用的是Smart SVN 客户端. Smart SVN 这个工具总体还是挺不错的! 在代码的提交和获 ...

  5. 我来说说java的NIO

      Java NIO的出现旨在提高文件的读写速度,当然IO用NIO重新实过,所以我们不用显示的调用NIO也能享受这种高效的文件读写. Java NIO的高效得益于其两大"助手":C ...

  6. Java递归调用改成非递归

          在java语言中,使用递归调用时,如果过多的调用容易造成java.lang.StackOverflowError即栈溢出和程序执行过慢.这是一个潜在Bug和影响程序执行效率问题,需要谨慎使 ...

  7. Oracle Recycle Bin

    开启回收站RECYCLEBIN=ON,默认开启 ALTER SYSTEM SET RECYCLEBIN=OFF SCOPE=SPFILE; 一.从回收站还原表 还原删除的表和从属对象. 如果多个回收站 ...

  8. 8.2.6 PEB —— PEB结构值不正确的问题

    书中作者使用 dt _PEB xxxxxx 命令来查看当前进程的PEB结构. 实际操作后PEB结构显示的成员值: 作为进程链表的LDR结构居然没有值,这显然是不正常的,地址也没有输错,问题到底出在哪里 ...

  9. 8.3.3 快速系统调用 —— XP SP3上SystemCallStub的奇怪问题

    依书上的例子,ReadFile()函数会调用ntdll!NtReadFile(),后者将服务号放到eax之中,然后调用SharedUserData!SystemCallStub(),由此函数执行sys ...

  10. AWS Data Lake Service Stack