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. HDU 3108 Ant Trip

    Ant Trip Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  2. Experience Design for Sexable Forum

    Mars March 16, 2015

  3. so near yet so far

    Dear little yang So beautiful boy as you, the most beautiful boy is you who i ever saw, like a sun , ...

  4. Vue源代码笔记(一)数据绑定

    VUE数据绑定介绍 数据绑定是vue的基础核心之一,本文以Vue对象(当然也包含VueComponent)里的data数据绑定为例,阐述整个绑定的过程. Vue的数据绑定由三部分组成, Observe ...

  5. POJ 2373 单调队列优化DP

    题意: 思路: f[i] = min(f[j]) + 1; 2 * a <= i - j <= 2 *b: i表示当前在第i个点.f[i]表示当前最少的线段个数 先是N^2的朴素DP(果断 ...

  6. tomcat web容器工作原理

    Tomcat的模块结构设计的相当好,而且其Web 容器的性能相当出色.JBoss直接就使用了Tomcat的web容器,WebLogic的早期版本也是使用了Tomcat的代码.Web容器的工作过程在下面 ...

  7. linux 下 .sh 文件语法

    转自:http://blog.sina.com.cn/s/blog_54f82cc201010hfz.html 介绍: 1 开头 程序必须以下面的行开始(必须方在文件的第一行): #!/bin/sh ...

  8. 使用PXE+NFS EFI引导安装RHEL6/7以及Kickstart安装

    PXE引导的步骤: 1.开机后选择网络启动,client端向server端的dhcpd发起获取IP地址的dhcp请求. 2.server端分配IP后,dhcpd会同时根据其配置文件,通过TFTP协议发 ...

  9. 紫书 例题 10-14 UVa 12034(组合数+递推)

    这道题有点类似动态规划,设答案为f(n) 第一个人有i个人,就有c(n,i)种可能 然后后面有f(n-i)种可能,所以相乘,然后枚举所有可能加起来就ok了. #include<cstdio> ...

  10. HDU 4862 Jump 费用流

    又是一个看了题解以后还坑了一天的题…… 结果最后发现是抄代码的时候少写了一个负号. 题意: 有一个n*m的网格,其中每个格子上都有0~9的数字.现在你可以玩K次游戏. 一次游戏是这样定义的: 你可以选 ...