[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 传说中,有个神奇的潘多拉宝盒.如果谁能打开,便可以拥有幸福.财富.爱情.可是直到真的打开,才发现与之 相随的还有灾难.不幸.其实,在潘多拉制造这个宝盒的时候,设置了一些咒语来封 ...
随机推荐
- 深入理解synchronize
本文参考引用,本人整理个人理解.地址点击 1.实现原理 synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性. 下面是一些 ...
- Entity Framework(一)
相关知识点复习: 1.var 类型推断: var p=new Person(); 2.匿名类型: var a=new {Name="wang",Age=12 }; 3.给新创建的 ...
- ironic images
参考: http://blog.csdn.net/wanghuiict/article/details/52757359 ironic 整个部署流程中有两组映像,分别是 deploy 映像和 user ...
- 【志银】nginx_php_mysql_phpMyAdmin配置(Windows)
✄更新中... 更新日期:2018.11.22 ★版本说明+快捷下载(官网) nginx nginx-1.14.1 http://nginx.org/download/nginx-1.14.1. ...
- 网易2017校园招聘算法题c语言实现源码
题目: 给定一个数组,除了一个数出现1次之外,其余数都出现3次.找出出现一次的数.如:{1, 2, 1, 2, 1, 2, 7}, 找出7. 格式: 第一行输入一个数n,代表数组的长度,接下来一行输入 ...
- UVALive 5027 二分图 EK
C - Card Game Crawling in process...Crawling failedTime Limit:3000MS Memory Limit:0KB 64bit IO ...
- Axios & Interceptors & Serialization & CORS & cookie
Axios https://github.com/axios/axios#config-defaults Global axios defaults axios.defaults.baseURL = ...
- KNN算法在保险业精准营销中的应用
版权所有,可以转载,禁止修改.转载请注明作者以及原文链接. 一.KNN算法概述 KNN是Machine Learning领域一个简单又实用的算法,与之前讨论过的算法主要存在两点不同: 它是一种非参方法 ...
- P4113 [HEOI2012]采花
题目描述 萧薰儿是古国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花. 花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便于 ...
- [bzoj4372] 烁烁的游戏 [动态点分治+线段树+容斥原理]
题面 传送门 思路 观察一下题目,要求的是修改"距离点$u$的距离一定的点权值",那这个就不能用传统的dfs序类算法+线段树维护,因为涉及到向父亲回溯的问题 看到和树上距离相关的东 ...