题目:

链接

大意:

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

思路:

有向图上求包含节点数最多的路径的节点数 可直接使用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. 【leetcode】638. Shopping Offers

    题目如下: In LeetCode Store, there are some kinds of items to sell. Each item has a price. However, ther ...

  2. Python 元组Ⅱ

    删除元组 元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组,如下实例: 以上实例元组被删除后,输出变量会有异常信息,输出如下所示: 元组运算符 与字符串一样,元组之间可以使用 + ...

  3. mysql分组排序加序号

    参照https://www.cnblogs.com/CharlieLau/p/6737243.html 一.需求 新加一个Sort 字段,初始值为1,按照parentID分组添加sort值. 根据原数 ...

  4. 各种注意事项(还有c++的一些操作)

    转c++时间: 2017年8月9号 1.记得打头文件 2.=与==的区别(赋值|比较) 3.各种运算符的比较级(与Pascal不同),主要是==与位运算 *4.在OJ上scanf和printf时间优于 ...

  5. mysql FIRST()函数 语法

    mysql FIRST()函数 语法 作用:返回指定的字段中第一个记录的值.直线电机选型 语法:SELECT FIRST(column_name) FROM table_name 注释:可使用 ORD ...

  6. React 初试

    小Demo, 后面会进行拓展的 import React from 'react'; import ReactDOM from 'react-dom'; class Welcome extends R ...

  7. 安装mariadb报错: Job for mariadb.service failed because the control process exited with error code. See "systemctl status mariadb.service" and "journalctl -xe" for details.

    卸载和删除都使用过了,没有起到效果,然后用了如下的方案,进行解决: CentOS 从 Yum 源安装配置 Mariadb 2017.03.01 WangYan 学习笔记  热度 7℃ 一.安装 Mar ...

  8. 误用 Kotlin 中的 sortedWith() 方法排序,集合没有变化

    时间:2019年8月4日14:17:06问题描述:看下边的小例子: data class Man(val name: String, val age: Int, val type: Int) fun ...

  9. Python 写 ACM 题目的一些技巧

    目录 输入输出 input() 输入 split() 用于输入 strip() 输入清理 print() 输入 sort 排序 输入输出 input() 输入 Python3 中 input() 函数 ...

  10. centos7 升级php版本

    centos7 默认PHP5.4,版本太低,很多要求至少PHP5.5 1.查看已经安装的PHP组件 yum list installed| grep php php.x86_64 -.el7 @bas ...