题目:

链接

大意:

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

思路:

有向图上求包含节点数最多的路径的节点数 可直接使用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 ;
}

最新文章

  1. C# 使用 StructLayoutAttribute 时 C# /C++ 内存空间分配与成员对齐问题
  2. git 一般的使用操作
  3. (medium)LeetCode 264.Ugly Number II
  4. iTerm2 + oh my zsh代替mac自带的bash shell
  5. Linux CPU数量判断,通过/proc/cpuinfo.
  6. [Redux] Extracting Container Components -- Complete
  7. HTML5开发入门经典教程和案例合集(含视频教程)
  8. Please verify you invoked Maven from the correct directory
  9. linux安装和配置 mysql、redis 过程中遇到的问题记录(转)
  10. 前端开发IDE VSCode + live preview
  11. 解决面板里没有network manager图标的问题 ,也就是在桌面环境下,没有那个网络图标
  12. HTTPS抓包之Charles
  13. Change事件多参
  14. Mybatis 使用 mapper 接口规范的 一对一, 一对多,多对多映射
  15. cocos2d-x 3.0 正式版 项目创建
  16. [PY3]——函数——函数注解 | 实现类型检查功能
  17. 中南月赛 1313: ZZY的宠物
  18. mysql-bin.000001
  19. 【题解】HNOI2016树
  20. 集合 Vector ArrayList 集合一

热门文章

  1. electron-vue打包引用的图标不显示问题
  2. 【curl】cookie的分隔符
  3. postman-变量
  4. luoguP1255 数楼梯 x
  5. Selenium 元素常用操作方法(键盘和鼠标事件)
  6. linux服务器在线测速
  7. sqli-labs(35)
  8. C# 前台和后台POST提交信息的实现方法
  9. C#实现读取指定盘符硬盘序列号的方法
  10. nginx调优buffer参数设置