hdu 5325 Crazy Bobo 拓扑排序
来源:互联网 发布:ant 打包java指定目录 编辑:程序博客网 时间:2024/05/16 15:13
题意:
给你一棵树,每个节点上都有一个权值。
让你找到一个连通的节点集合,使得根据节点权值升序排序后,第i个节点到第i+1个节点所经过的其它节点权值都小于第i个节点的权值。
问你这样的集合最大的size。
思路:
比较朴素的思路:枚举以每个节点作为根,进行dfs搜寻所有比父亲节点权值大的节点个数,复杂度n^2。如果我们开一个数组保存之前已经统计过的节点个数,则复杂度降为O(n)。
赛中我们队是dfs开栈交c++过的,但实际这并非正解。
后来问过出题人,杭电的栈虽小,但若可以使用开栈代码,则内存有多大就可以开多大。50万正常来说是承受不了的,普通正常赛事中栈深大概就26万。
正解:拓扑排序。根据输入建边,权值大的指向权值小的。
code1(拓扑排序、正解):
//#pragma comment(linker, "/STACK:1024000000,1024000000") #include <bits/stdc++.h>using namespace std;const int N = 5e5+5;typedef long long LL;int n;int w[N];int cnt[N];int ind[N];vector <int> edge[N];void solve() { fill(cnt+1, cnt+n+1, 1); queue <int> q; for(int i = 1;i <= n; i++) if(ind[i] == 0) q.push(i); while(!q.empty()) { int u = q.front(); q.pop(); for(auto &v:edge[u]) { //if(w[i] < w[u]) continue; cnt[v] += cnt[u]; if(--ind[v] == 0) q.push(v); } } int res = 0; for(int i = 1;i <= n; i++) res = max(res, cnt[i]); printf("%d\n", res);}int main() { while(scanf("%d", &n) != EOF) { fill(edge+1, edge+n+1, vector <int>()); fill(ind+1, ind+n+1, 0); for(int i = 1;i <= n; i++) scanf("%d", &w[i]); for(int i = 1;i <= n-1; i++) { int u, v; scanf("%d%d", &u, &v); if(w[u] < w[v]) swap(u, v); edge[u].push_back(v); ind[v]++; } solve(); } return 0;}
#include <cstdio>#include <cstring>#include <iostream>#include <cstdlib>#include <algorithm>#include <vector>#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std;const int N = 5e5+5;typedef long long LL;int n;int a[N];int cnt[N];bool vis[N];vector <int> edge[N];int dfs(int u, int p) { int ret = 0; vis[u] = true; for(auto &v : edge[u]) { if(v == p) continue; if(a[v] < a[u]) continue; if(vis[v]) ret += cnt[v]; else ret += dfs(v, u); } cnt[u] = ret+1; return ret+1;}void solve() { int res = 0; for(int i = 1;i <= n; i++){ if(vis[i]) res = max(res, cnt[i]); else res = max(res, dfs(i, -1)); } printf("%d\n", res);} int main() { while(scanf("%d", &n) != EOF) { for(int i = 1;i <= n; i++){ edge[i].clear(); vis[i] = false; cnt[i] = 0; } for(int i = 1;i <= n; i++) scanf("%d", &a[i]); for(int i = 1;i <= n-1; i++) { int u, v; scanf("%d%d", &u, &v); edge[u].push_back(v); edge[v].push_back(u); } solve(); } return 0;}
0 0
- hdu 5325 Crazy Bobo 拓扑排序
- Hdu 5325 Crazy Bobo (拓扑排序)
- HDU 5325 CRAZY BOBO 排序
- HDU 5325 Crazy Bobo
- hdu 5325 Crazy Bobo
- HDU 5325 Crazy Bobo
- hdu 5325 Crazy Bobo
- HDU 5325 Crazy Bobo
- hdu 5325 Crazy Bobo (拓扑排序代替树的遍历解决爆栈)
- 多校第三场 1010 hdu 5325 Crazy Bobo(拓扑排序+树形dp)
- HDU 5325 - Crazy Bobo(DFS)
- hdu 5325 Crazy Bobo dfs
- HDU 5325 Crazy Bobo(深搜)
- hdu 5325 Crazy Bobo 乱搞+搜索
- hdu 5325 Crazy Bobo(树形dp)
- hdu 5325 Crazy Bobo 多校1010
- HDU 5325 Crazy Bobo(思路+dfs 记忆化)
- hdu-5325 Crazy Bobo (2015 Multi-University Training Contest 3)
- Spiral Matrix II
- 移动H5前端性能优化指南
- 用java做了个控制台版的2048
- 怎么学习一个开源框架
- UE4学习笔记9th
- hdu 5325 Crazy Bobo 拓扑排序
- HDU-5319 Painter
- Python用Bottle轻量级框架进行Web开发
- C# 导入EXCEL 报错外部表不是预期的格式错误
- Oracle 表id实现自增
- Xcode7 不能使用http网络请求
- cereal:C++实现的开源序列化库
- HDU 4006 The kth great number 【队列】
- Android View的onTouchEvent和OnTouch区别