[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 传说中,有个神奇的潘多拉宝盒.如果谁能打开,便可以拥有幸福.财富.爱情.可是直到真的打开,才发现与之 相随的还有灾难.不幸.其实,在潘多拉制造这个宝盒的时候,设置了一些咒语来封 ...
随机推荐
- cloud-init简介及组件说明
http://cloudinit.readthedocs.io/en/latest/topics/examples.html介绍: cloud-init是专为云环境中虚拟机的初始化而开发的工具, ...
- 原始套接字--icmp相关
icmp请求 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <uni ...
- 团队Alpha版本冲刺(四)
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:何家伟 组员8:政演 组员9:鸿杰 组员10:刘一好 组员:何宇恒 展示组内最新 ...
- Alpha 冲刺
队名:我头发呢队 组长博客 作业博客 杰(组长) 过去两天完成了哪些任务 查阅Python爬取音源的资料,如 Python3爬虫抓取网易云音乐热评实战 Python爬取高品质QQ音乐(2) 如何爬网易 ...
- URAL 1934 spfa算法
D - Black Spot Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Subm ...
- select chosen 禁用下拉框某一个option
$("#tbParBudCode option[value='" + budCodeId + "']").attr("disabled", ...
- C#类和类成员初始化顺序
1.不带静态成员的普通类,首先通过构造函数初始化. 2.带静态属性的类,无论是普通类还是静态类,都会先初始化静态字段,再执行构造函数. 3.类初始化时,不会执行类中方法,无论是否是静态.若想执行方法, ...
- DataBase -- SQL INNER JOIN
SQL INNER JOIN 关键字 在表中存在至少一个匹配时,INNER JOIN关键字返回行. INNER JIN关键字语法 SELECT column_name(s) FROM table_na ...
- [转]busybox中telnet 功能添加
使用busybox制作的一个基本根文件系统如何添加telnetd服务呢? 下面把本人的添加过程列出来供大家分享,如有不同意见请不吝赐教! 1. 添加telnet的支持(busybox中配置) Netw ...
- 用IE滤镜实现的一些特效
CSS3是当下非常火的一个话题,很多浏览器都已经开始支持这一特性,然后IE这个拥有庞大用户群体的平台,却无法提供这样的支持,即便是IE9发布,也无法改变这一事实,然而,幸运的是,IE并非在这方面毫无作 ...