Description

传说中,有个神奇的潘多拉宝盒。如果谁能打开,便可以拥有幸福、财富、爱情。可是直到真的打开,才发现与之
相随的还有灾难、不幸。其实,在潘多拉制造这个宝盒的时候,设置了一些咒语来封锁住灾难与不幸。然而,直到
科技高度发达的今天,人们才有希望弄懂这些咒语。所以说,上千年来,人们只得忍受着各种各样的疾病和死亡的
痛苦。然而,人类的命运从此改变了。经过数十年的研究,NOI组织在最近终于弄清楚了潘多拉咒语的原理。咒语
是由一个叫做咒语机的机器产生的。用现在的名词来解释,咒语机其实就是一个二进制产生器,它产生的一个二进
制字符串(这个字符串叫做咒语源)经加密后就形成了咒语。二进制产生器的结构是这样的:它由n个元件组成,
不妨设这n个元件的标号为0到n-1。在每个时刻,都有且仅有一个信号,它停留在某个元件上。一个信号就是一个
二进制字符串。最开始,有一个空串信号停留在元件0上。在某个时刻,如果有一个信号s停留在元件I上,那么,
这时元件i可以将信号后面加一个0,然后把信号传给元件pi,0,也可以将信号后面加一个1,然后传给元件pi,1。也
就是说,下一个时刻有可能,一种可能是一个信号S0(表示字串S后面加一个0形成的字串)仪在元件pi,0上,另一
种可能是有一个信号S1停留在元件pi,1上。有的元件可以将停留在它上面的信号输出,而输出的信号就成为了咒语
源,这样的元件叫做咒语源输出元。不难发现,有些口语源是可能由一个咒语机产生的,而另一些咒语源则不行。
例如,下图的咒语机能产生1,11,111,1111,...等咒语源,但是不能产生0,10,101等咒语源。在这个盒子上,有K个
咒语机,不妨将这些咒语机从0到K-1标号。可能有这种情况,一个咒语机i能够产生的口语源,咒语机j都能产生。
这时,我们称咒语机j是咒语机i的升级。而衡量这个例子的复杂程度的一种办法是:看这个盒子上升级次数最多的
一个咒语机。即:找到一个最长的升级序列a1,a2...at。该升级序列满足:序列中任意两个咒语机的标号都不同,
且都是0到k-1(包含0和k-1)之间的整数,且咒语机a2是咒语机a1的升级,咒语机a3是咒语机a2的升级...,咒语
机at是咒语机at-1的升级。你想远离灾难与不幸吗?你想从今以后沐浴幸福的阳光吗?请打开你的潘多拉之盒吧。
不过在拱形它之前,你先得计算一下宝盒上最长的升级序列。

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

解题思路:

考虑升级关系的判定。
枚举两个图。
由于这个图的特殊性,那就是永远不会失配。
那么我们就只需要判定输出位置就好了。
由于具有高度循环性,只需要Bfs一遍判断就好了。
最后判断包含关系,很显然图中具有传递性
而传递回来只能说明图之间等价。
那么就tarjan缩点跑个Dp就好了。
代码:
 #include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
struct Pr_ma{
struct pnt_{
int ch[];
bool out;
}p[];
int n,m;
int can;
int f;
void Insert(void)
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int id;
scanf("%d",&id);
p[id].out=true;
}
for(int i=;i<n;i++)
scanf("%d%d",&p[i].ch[],&p[i].ch[]);
return ;
}
}pr[];
struct pnt{
int hd;
int dfn;
int low;
int blg;
bool vis;
void res(int x)
{
dfn=low=x;
return ;
}
}p[];
struct pnt_{
int hd;
int wgt;
int ind;
}p_[];
struct ent{
int twd;
int lst;
}e[],e_[];
struct int_{int x;int y;};
int n;
int cnt;
int s_t;
int c_t;
int stt;
int col;
int cnt_;
int dp[];
int sta[];
int_ stack_[];
bool vis[][];
std::queue<int>Q;
std::queue<int_>Q_;
void ade(int f,int t)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
return ;
}
void ade_(int f_,int t_)
{
cnt_++;
e_[cnt_].twd=t_;
e_[cnt_].lst=p_[f_].hd;
p_[f_].hd=cnt_;
p_[t_].ind++;
return ;
}
bool Bfs(Pr_ma x_,Pr_ma y_)
{
while(!Q_.empty())Q_.pop();
memset(vis,,sizeof(vis));
Q_.push(stack_[]);
while(!Q_.empty())
{
int_ h=Q_.front();Q_.pop();
if(vis[h.x][h.y])continue;
vis[h.x][h.y]=true;
stack_[++s_t]=h;
if(x_.p[h.x].out&&!y_.p[h.y].out)return false;
int nx,ny;
for(int c=;c<;c++)
{
nx=x_.p[h.x].ch[c];
ny=y_.p[h.y].ch[c];
Q_.push((int_){nx,ny});
}
}
return true;
}
void tarjan(int x)
{
p[x].vis=true;
sta[++stt]=x;
p[x].res(++c_t);
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].dfn&&!p[to].blg)
p[x].low=std::min(p[x].low,p[to].dfn);
else if(!p[to].dfn)
{
tarjan(to);
p[x].low=std::min(p[x].low,p[to].low);
}
}
if(p[x].dfn==p[x].low)
{
col++;
int u;
do{
p_[col].wgt++;
u=sta[stt--];
p[u].blg=col;
}while(u!=x);
}
return ;
}
int Top_sort(void)
{
while(!Q.empty())Q.pop();
int ans=;
for(int i=;i<=col;i++)if(!p_[i].ind)
Q.push(i);
while(!Q.empty())
{
int x=Q.front();Q.pop();
dp[x]+=p_[x].wgt;
for(int i=p_[x].hd;i;i=e_[i].lst)
{
int to=e_[i].twd;
p_[to].ind--;
dp[to]=std::max(dp[to],dp[x]);
if(!p_[to].ind)Q.push(to);
}
ans=std::max(ans,dp[x]);
}
return ans;
}
int main()
{
// freopen("pandora.in","r",stdin);
// freopen("pandora.out","w",stdout);
scanf("%d",&n);
for(int i=;i<=n;i++)pr[i].Insert();
for(int i=,j;i<=n;i++)for(j=;j<=n;j++)if(i!=j)
if(Bfs(pr[i],pr[j]))ade(i,j);
for(int i=;i<=n;i++)if(!p[i].blg)
tarjan(i);
// for(int i=1;i<=n;i++)printf("%d\n",p[i].blg);
for(int u=;u<=n;u++)
{
for(int i=p[u].hd;i;i=e[i].lst)
{
int v=e[i].twd;
int x=p[u].blg;
int y=p[v].blg;
if(x!=y)ade_(x,y);
}
}
printf("%d\n",Top_sort());
return ;
}

BZOJ1194: [HNOI2006]潘多拉的盒子(tarjan)的更多相关文章

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

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

  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. 【BZOJ-1194】潘多拉的盒子 拓扑排序 + DP

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

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

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

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

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

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

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

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

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

  9. HNOI2006 潘多拉的盒子

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

随机推荐

  1. 微信公众号开发将war包导入新浪sae出现错误

    JAVA_Error: Error for /wechat.do java.lang.NoSuchFieldError: INSTANCE at org.apache.http.impl.io.Def ...

  2. Android学习笔记(9):使用XML文件和Java代码控制UI界面

    Android推荐使用XML文件设置UI界面.然后用Java代码控制逻辑部分,这体现了MVC思想. MVC全名是Model View Controller.是模型(model)-视图(view)-控制 ...

  3. ubuntu 非长期支持版升级系统版本号(ssh登录情况适用)

    (1)当前系统为非长期支持版.而且已被废弃,仅仅能逐版本号升级 以当前系统版本号为11.10为例 改动source.list更新源为通用old源,由于原来的源已经不可用 deb http://old- ...

  4. DBCC-->Database Console Commands

    https://docs.microsoft.com/en-us/sql/t-sql/database-console-commands/database-console-commands DBCC ...

  5. nyoj--46--最少乘法次数(数学+技巧)

    最少乘法次数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 给你一个非零整数,让你求这个数的n次方,每次相乘的结果可以在后面使用,求至少需要多少次乘.如24:2*2=2 ...

  6. [JZOJ4272] [NOIP2015模拟10.28B组] 序章-弗兰德的秘密 解题报告(树形DP)

    Description 背景介绍弗兰德,我不知道这个地方对我意味着什么.这里是一切开始的地方.3年前,还是个什么都没见过的少年,来到弗兰德的树下,走进了封闭的密室,扭动的封尘已久机关,在石板上知道了这 ...

  7. 美国人教你这样用Google,你真的会变特工

    转自微博:黑客师: 用了这么久的谷歌,今天才发现. 第一篇 在搜索框上输入:“indexof/”inurl:lib 再按搜索你将进入许多图书馆,并且一定能下载自己喜欢的书籍. 在搜索框上输入:“ind ...

  8. Python json数据中文输出问题。

    这个问题困扰了我好久好久,最后看了一眼官方文档,解决问题了. 问题描述:从web上获取的json数据,然后对应的保存到了python的类型中.再次输出这个数据时,中文总会变成\u1234这种形式. P ...

  9. win10安装jdk8 配置环境变量

    参考:https://jingyan.baidu.com/article/6b97984dd257b41ca2b0bf86.html  

  10. 运维派 企业面试题3 为上题中的 "十个随机字母_test.html" 文件 更名

    Linux运维必会的实战编程笔试题(19题) 企业面试题3 #将试题2中创建的文件名uopiyhgawe_test.html# test-->修改为omg,html-->HTML 方法一: ...