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


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
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
题目大意:咒语机中的元件每个都有两种情况,即把信号处理后把信号传给两个对应的元件,若信号传给了输出元件,那么就可以得到一个种类的信号。设每个咒语机可以产生若干种信号,那么找到一个最长上升序列使得序列中的每一个咒语机都能生成他之前每一个咒语机能生成的信号。
大概思路:我们可以先枚举两个咒语机之间的关系(比如咒语机a产生的信号种类数比咒语机b产生的信号种类数多),即让两个咒语机都一直向添加1移动或一直向添加0移动,若某个咒语机搜索时先遇到输出机,那么这个咒语机产生的信号种类一定比另一个多。枚举时按照a属于b的关系建立单向边。然后Tarjan缩点找最长链即可。
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int S,a,b,f,cnt,dfs_num,CN,top,re_cnt,maxn=;
int pre[],dye[],DFN[],LOW[],size[],in_tow[],tow[],re_pre[],ans[];
int print[][],jdg[][];
int move[][][];
struct pack{int from,to,next;} E[],re_E[];
void add_edge(int x,int y){
E[++cnt].to=y;
E[cnt].next=pre[x];
E[cnt].from=x;
pre[x]=cnt;
}
void rebuild(){
for(int i=;i<=S;++i)
for(int j=pre[i];j;j=E[j].next)
if(dye[i]!=dye[E[j].to]){
re_E[++re_cnt].to=dye[E[j].to];
re_E[re_cnt].next=re_pre[dye[i]];
re_E[re_cnt].from=dye[i];
re_pre[dye[i]]=re_cnt;
}
}
void dfs(int p,int q){
if(jdg[p][q]||f) return ;
jdg[p][q]=;
if(print[b][q]&&!print[a][p]) {f=;return ;}
dfs(move[a][p][],move[b][q][]);
dfs(move[a][p][],move[b][q][]);
}
int check(){
f=;memset(jdg,,sizeof(jdg));
dfs(,);
return !f;
}
void tarjan(int pos){
DFN[pos]=LOW[pos]=++dfs_num;
in_tow[tow[++top]=pos]=;
for(int i=pre[pos];i;i=E[i].next){
if(!DFN[E[i].to]){
tarjan(E[i].to);
LOW[pos]=min(LOW[pos],LOW[E[i].to]);
}
else if(in_tow[E[i].to])
LOW[pos]=min(LOW[pos],DFN[E[i].to]);
}
if(DFN[pos]==LOW[pos]){
in_tow[pos]=;
size[dye[pos]=++CN]++;
while(pos!=tow[top]){
size[dye[tow[top]]=CN]++;
in_tow[tow[top--]]=;
}
--top;
}
}
int req(int v){
if(ans[v]) return ans[v];
ans[v]=size[v];
for(int i=re_pre[v];i;i=re_E[i].next)
ans[v]=max(ans[v],req(re_E[i].to)+size[v]);
return ans[v];
}
int find_max(){
for(int i=;i<=CN;++i) maxn=max(maxn,req(i));
return maxn;
}
int main(){
scanf("%d",&S);
for(int i=;i<=S;++i){
int n,m;
scanf("%d%d",&n,&m);
for(int j=;j<=m;++j){
int t;
scanf("%d",&t);
print[i][t+]=;
}
for(int j=;j<=n;++j){
int t,tt;
scanf("%d%d",&t,&tt);
move[i][j][]=t+;
move[i][j][]=tt+;
}
}
for(int i=;i<=S;++i)
for(int j=;j<=S;++j)
if(i!=j){
a=i;
b=j;
if(check()) add_edge(i,j);
}
for(int i=;i<=S;++i)
if(!dye[i])
tarjan(i);
rebuild();
printf("%d",find_max());
return ;
}
[BZOJ1194][HNOI2006][强连通分量Tarjan+dfs]潘多拉的盒子的更多相关文章
- 强连通分量(tarjan求强连通分量)
双DFS方法就是正dfs扫一遍,然后将边反向dfs扫一遍.<挑战程序设计>上有说明. 双dfs代码: #include <iostream> #include <cstd ...
- 图论(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的最长路.. ------------------------------------- ...
- 求图的强连通分量--tarjan算法
一:tarjan算法详解 ◦思想: ◦ ◦做一遍DFS,用dfn[i]表示编号为i的节点在DFS过程中的访问序号(也可以叫做开始时间)用low[i]表示i节点DFS过程中i的下方节点所能到达的开始时间 ...
- 【有向图】强连通分量-Tarjan算法
好久没写博客了(都怪作业太多,绝对不是我玩的太嗨了) 所以今天要写的是一个高大上的东西:强连通 首先,是一些强连通相关的定义 //来自度娘 1.强连通图(Strongly Connected Grap ...
- 【BZOJ-1194】潘多拉的盒子 拓扑排序 + DP
1194: [HNOI2006]潘多拉的盒子 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 456 Solved: 215[Submit][Stat ...
- 1194: [HNOI2006]潘多拉的盒子
1194: [HNOI2006]潘多拉的盒子 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 464 Solved: 221[Submit][Stat ...
- 【强连通分量】Bzoj1194 HNOI2006 潘多拉的盒子
Description Sulotion 首先要对每对咒语机建图,判断机器a是否能生成所有机器b生成的 如果跑一个相同的串,最后结束的点b可输出a不可输出,判断就为否 大概就用这种思路,f[x][y] ...
- BZOJ1194: [HNOI2006]潘多拉的盒子(tarjan)
Description 传说中,有个神奇的潘多拉宝盒.如果谁能打开,便可以拥有幸福.财富.爱情.可是直到真的打开,才发现与之 相随的还有灾难.不幸.其实,在潘多拉制造这个宝盒的时候,设置了一些咒语来封 ...
随机推荐
- unity值得推荐的网址
免费字体下载网站:http://www.dafont.com/ 免费声音文件下载网站:http://freesound.org/ http://incompetech.com/mus ...
- leetcode 201. 数字范围按位与 解题报告
给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点). 示例 1: 输入: [5,7] 输出: 4 ...
- [转]Android的网络与通信
本文转自:http://www.cnblogs.com/qingblog/archive/2012/06/15/2550735.html 第一部分 Android网络基础 Android平台浏览器 ...
- Java常用实体类
System类 访问系统属性 - 遍历 package org.zln.usefulclass.system; import java.util.Properties; /** * Created b ...
- Codeforces Round #386 (Div. 2) 746G(树的构造)
大体题意 一棵树有n个结点,告诉你每层深度上有a[i]个结点,以及有多少叶子结点 让你生成这棵树 题解:考虑一颗树,如果满足每层深度上有a[i]结点,最多能有多少叶子结点 那么答案很简单,就是对(a[ ...
- [CF932D]Tree
题目大意:两种操作: $1\;u\;w:$把下一个点挂在$u$下,权值为$w$. $2\;u\;w:$询问从$u$开始的序列的最长长度.序列为从$u$开始的祖先序列中的不严格上升序列 题解:可以把一个 ...
- POJ 2243 [SDOI2011]染色 | 树链剖分+线段树
原题链接 肯定是树链剖分的题啦 树剖怎么做可以看我上一篇博客 如果我们已经剖完了: 然后考虑怎么维护重链和查询 用线段树维护的时候当前区间的区间颜色个数应该等于左儿子+右儿子,但是当左儿子的右端点和右 ...
- sass mixin 持续更新
控制多行显示省略号... //文字溢出省略号@mixin coveText($num:1){ @if $num == 1{ white-space: normal; overflow: hidden; ...
- 【Error】Python:UnicodeDecodeError: ‘XXX' codec can't decode bytes in position... 解决方法
错误信息: UnicodeDecodeError: ‘XXX' codec can't decode bytes in position 2-5: illegal multibyte sequence ...
- ZOJ 3822 Domination (三维概率DP)
E - Domination Time Limit:8000MS Memory Limit:131072KB 64bit IO Format:%lld & %llu Submi ...