[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 传说中,有个神奇的潘多拉宝盒.如果谁能打开,便可以拥有幸福.财富.爱情.可是直到真的打开,才发现与之 相随的还有灾难.不幸.其实,在潘多拉制造这个宝盒的时候,设置了一些咒语来封 ...
随机推荐
- ASP.NET Core [2]:Middleware-请求管道的构成(笔记)
原文链接:http://www.cnblogs.com/RainingNight/p/middleware-in-asp-net-core.html 中间件处理请求主要分为三个阶段:1. 中间件的注册 ...
- Python namedtuple(命名元组)使用实例
Python namedtuple(命名元组)使用实例 #!/usr/bin/python3 import collections MyTupleClass = collections.namedtu ...
- Day3 UI:7种常用控件、4种基本布局
Android常用控件 TextView <TextView android:id="@+id/text_view" android:layout_width="m ...
- Small组件化重构安卓项目
如果从一开始就没有设计好 后面项目业务比较大的时候很难掉头
- 大图轮播js
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> ...
- HDU 1709 母函数天平问题 可出现减法的情况 The Balance
The Balance Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 爬虫python
最近看到电影,也看了很多的评论,想了解下大多人对相关电影的评论,正好也在学习Python,就利用其爬虫的强大能力,这里利用Python3.6.1 下面是相关代码: #coding:utf-8 __au ...
- 深入解析vue.js响应式原理与实现
vue.js响应式原理解析与实现.angularjs是通过脏检查来实现数据监测以及页面更新渲染.之后,再接触了vue.js,当时也一度很好奇vue.js是如何监测数据更新并且重新渲染页面.vue.js ...
- [blockchain-035]eos的部署安装智能合约
0.参考资料 https://github.com/EOSIO/eos/wiki 1. eos的github地址 https://github.com/EOSIO/eos 2.下载eos源码 git ...
- [LeetCode169]Majority Element
Majority Element Total Accepted: 58500 Total Submissions: 163658My Submissions Question Solution Gi ...