题目:

链接

大意:

盒子与盒子之间的关系构成一个有向图 求图上包含节点数最多的路径的节点数

思路:

有向图上求包含节点数最多的路径的节点数 可直接使用tarjan缩点后拓扑dp求得 在此不赘述

此题重点是如何判定盒子与盒子之间的关系

首先我们要有一个共识 盒子的起点一致 一个盒子包含另一个盒子相当于它可以走另一个盒子到不了的路 换句话说 一个盒子不是另一个盒子的下属当且仅当它能够到另外一个盒子走不到的地方

而与此同时此题的数据范围非常的小 所以我们可以有一点大胆的想法

判定两只笔谁真谁伪 我们可以判断写同一个字的表现来看 许多实验检验某一物的某一性质是否相同的原理都基本含有对照的思想

我们在这里也可以如此 两个盒子同时从起点出发 同时走一样的路径 走到谁不能走或双方走完为止(边全遍历完) 通过这样便可以判断盒子之间的关系

同时注意这里的判断是单向的即i属于不属于j 并没有判断j属不属于i所以两种情况都要考虑

至此算法也已经很明显了

下面是代码

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <queue>
#define MAXX 55
#define r(x) x=read()
using namespace std;
int lj[MAXX][MAXX][],map[MAXX][MAXX],put[MAXX][MAXX],flag[MAXX][MAXX],
id[MAXX],sta[MAXX],dfn[MAXX],low[MAXX],dp[MAXX],w[MAXX],
pre[MAXX],flag2[MAXX],ans,top,k,num,n;
int h[MAXX],cnt;
struct edge{int to,nex;}e[MAXX];
void add(int u,int to)
{
cnt++;
e[cnt]=(edge){to,h[u]};
h[u]=cnt;
}
typedef pair<int ,int >node;
void tarjan(int now)
{
low[now]=dfn[now]=++k;
sta[++top]=now;
for(int i=h[now];i;i=e[i].nex)
{
if(!dfn[e[i].to])
tarjan(e[i].to),low[now]=min(low[now],low[e[i].to]);
else
if(!id[e[i].to])
low[now]=min(low[now],dfn[e[i].to]);
}
if(dfn[now]==low[now])
{
id[now]=++num;
while(sta[top]!=now){id[sta[top]]=num,--top;}
--top;
}
}
bool bfs(int x,int y)
{
memset(flag,,sizeof(flag));
queue<node>que;
que.push(node(,));
while(!que.empty())
{
node p;
p=que.front();que.pop();
for(int i=;i<=;++i)
{
int x1=lj[x][p.first][i],y1=lj[y][p.second][i];
if(put[x][x1]&&!put[y][y1])
return ;
else
if(!flag[x1][y1])
que.push(node(x1,y1)),flag[x1][y1]=;
}
}
return ;
}
int read()
{
char ch=;int w=;
while(ch<''||ch>''){ch=getchar();}
while(ch>=''&&ch<=''){w=w*+ch-'';ch=getchar();}
return w;
}
int main()
{
r(n);
for(int t=;t<=n;++t)
{
int n1=,nm=,to=;
r(n1),r(nm);
for(int i=;i<=nm;++i)
r(to),put[t][to]=;
for(int i=;i<n1;++i)
for(int j=;j<=;++j)
r(to),lj[t][i][j]=to;
}
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
if(i!=j&&bfs(i,j))
add(i,j);
for(int i=;i<=n;++i)
if(!id[i])
tarjan(i);
for(int i=;i<=n;++i)
{
w[id[i]]+=;
for(int j=h[i];j;j=e[j].nex)
if(id[i]!=id[e[j].to])
map[id[i]][id[e[j].to]]=,++pre[id[e[j].to]];
}
queue<int>que;
for(int i=;i<=num;++i)
if(!pre[i])
que.push(i),dp[i]=w[i],ans=max(dp[i],ans);
while(!que.empty())
{
int p=que.front();que.pop();
for(int i=;i<=num;++i)
if(map[p][i])
{
dp[i]=max(dp[i],dp[p]+w[i]),ans=max(dp[i],ans);
if(!flag2[i])
que.push(i),flag2[i]=;
}
flag2[p]=;
}
printf("%d",ans);
return ;
}

Tarjan水题系列(3):HNOI2006 潘多拉的魔盒的更多相关文章

  1. Tarjan水题系列(5):最大半连通子图 [ZJOI2007 luogu P2272]

    题目 大意: 缩点后转为求最长链的长度和最长链的个数 思路: 看懂题就会做系列 长度和个数都可以拓扑排序后DP求得 毕竟是2007年的题 代码: 如下 #include <cstdio> ...

  2. Tarjan水题系列(4):HAOI2010 软件安装

    题目: 现在我们的手头有N个软件,对于一个软件i,它要占用Wi​的磁盘空间,它的价值为Vi​.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi​的和最大). ...

  3. Tarjan水题系列(2):HNOI2012 矿场搭建

    题目: 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之后 ...

  4. Tarjan水题系列(1):草鉴定Grass Cownoisseur [USACO15JAN]or[luogu P3119]

    题目如下: 约翰有n块草场,编号1到n,这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可能多的草场去品尝牧草. 贝西总是从1号草场出发,最后回到1号草场.她想经过尽可能多的草场,贝 ...

  5. 图论(Tarjan缩点):BZOJ 1194: [HNOI2006]潘多拉的盒子

    1194: [HNOI2006]潘多拉的盒子 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 344  Solved: 181[Submit][Stat ...

  6. BZOJ 1194: [HNOI2006]潘多拉的盒子( BFS + tarjan + dp )

    O(S²)枚举2个诅咒机, 然后O(n²)BFS去判断. 构成一个有向图, tarjan缩点, 然后就是求DAG的最长路.. ------------------------------------- ...

  7. nyoj 1208——水题系列——————【dp】

    水题系列 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述     给你一个有向图,每条边都有一定的权值,现在让你从图中的任意一点出发,每次走的边的权值必须必上一次的权 ...

  8. 1194: [HNOI2006]潘多拉的盒子

    1194: [HNOI2006]潘多拉的盒子 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 464  Solved: 221[Submit][Stat ...

  9. BZOJ1194: [HNOI2006]潘多拉的盒子(tarjan)

    Description 传说中,有个神奇的潘多拉宝盒.如果谁能打开,便可以拥有幸福.财富.爱情.可是直到真的打开,才发现与之 相随的还有灾难.不幸.其实,在潘多拉制造这个宝盒的时候,设置了一些咒语来封 ...

随机推荐

  1. 【NOIP2016提高A组模拟8.19】(雅礼联考day2)树上路径

    题目 给出一棵树,求出最小的k,使得,且在树中存在路径p,使得k>=S且k<=E.(k为路径p上的边的权值和). 分析 点分治,设当前为x的,求在以x为根的子树中,经过x的路径(包括起点或 ...

  2. Eclipse修改背景颜色(豆沙绿)

    操作界面默认颜色为白色.对于我们长期使用电脑编程的人来说,白色很刺激我们的眼睛,所以我经常会改变workspace的背景色,使眼睛舒服一些.设置方法如下: 1.打开window->Prefere ...

  3. express中app和router的区别

      var app = express(); var router = express.Router(); 以上二者的区别是什么,什么时候用哪个最合适? 区别看下面的例子: app.js var ex ...

  4. Python 运算符Ⅳ

    Python比较运算符 以下假设变量a为10,变量b为20: 以下实例演示了Python所有http://www.xuanhe.net/比较运算符的操作: 以上实例输出结果: Python赋值运算符 ...

  5. ArrayList,Vector ,LinkedList的存储性能和特性

    ArrayList,Vector,LinkedList : 两者都采用数组元素方式存储数据,此数组元素数大于实际存储的数据(以便于增加和插入元素),允许直接按照序号索引元素,但是插入元素涉及数组元素移 ...

  6. Spring Boot教程(二十三)使用Swagger2构建强大的RESTful API文档(2)

    添加文档内容 在完成了上述配置后,其实已经可以生产文档内容,但是这样的文档主要针对请求本身,而描述主要来源于函数等命名产生,对用户并不友好,我们通常需要自己增加一些说明来丰富文档内容.如下所示,我们通 ...

  7. [CSP-S模拟测试]:Six(数学)

    题目传送门(内部题85) 输入格式 一个正整数$N$. 输出格式 一个数表示答案对$1000000007$取模后的结果 样例 样例输入1: 样例输出1: 样例输入2: 样例输出2: 样例输入3: 样例 ...

  8. Hive、Spark优化案例

    一.Join原则 将条目少的表/子查询放在Join的左边.原因:在Join的reduce阶段,位于Join左边的表的内容会被加载进内存,条目少的表放在左边,可以减少发生内存溢出的几率. 小表关联大表: ...

  9. 理解BFC以及BFC相关布局问题解决

    写页面时会遇到: 子元素float父元素的高度不会撑开; 在布局时,box1and box2,其中box1 float:left,这是box2会在box1下面,(如果文字过多就会形成文字环绕效果),但 ...

  10. @清晰掉 c语言三"巨头" const:volatile:static

    const: 1.如果把const放在变量类型前,说明这个变量的值是保持不变的(即为常量),改变量必须在定义时初始化,初始化后对她的任何赋值都是非法的. 2.当指针或是引用指向一个常量时,必须在类型名 ...