/*
题意:给一个树,节点上有权值,问最多能找出多少个点满足在树上是连通的并且按照权值排序后相邻的点
在树上的路径权值都小于这两个点
DFS/BFS+思维:按照权值的大小,从小的到大的连有向边,搜索最多连接点数即是答案。因为排序后,他们之间的路径,
可定都是从当前节点u连过去的,那么都是小于这两个节点的。DFS需手动加栈,BFS类似拓扑排序的思路
*/
#pragma comment (linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; const int MAXN = 5e5 + ;
const int INF = 0x3f3f3f3f;
int w[MAXN];
int cnt[MAXN];
vector<int> G[MAXN];
int n; void DFS(int u) {
cnt[u] = ;
for (int i=; i<G[u].size (); ++i) {
int v = G[u][i];
if (!cnt[v]) DFS (v);
cnt[u] += cnt[v];
}
} int main(void) { //HDOJ 5325 Crazy Bobo
//freopen ("J.in", "r", stdin); while (scanf ("%d", &n) == ) {
for (int i=; i<=n; ++i) scanf ("%d", &w[i]);
for (int i=; i<=n; ++i) G[i].clear ();
for (int i=; i<=n-; ++i) {
int u, v; scanf ("%d%d", &u, &v);
if (w[u] < w[v]) G[u].push_back (v);
else G[v].push_back (u);
}
memset (cnt, , sizeof (cnt));
for (int i=; i<=n; ++i) {
if (cnt[i]) continue;
DFS (i);
}
int ans = ;
for (int i=; i<=n; ++i) ans = max (ans, cnt[i]);
printf ("%d\n", ans);
} return ;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std; const int MAXN = 5e5 + ;
const int INF = 0x3f3f3f3f;
int w[MAXN];
int cnt[MAXN];
int deg[MAXN];
vector<int> G[MAXN];
int n; int BFS(void) {
queue<int> Q; int ret = ;
for (int i=; i<=n; ++i) cnt[i] = ;
for (int i=; i<=n; ++i) {
if (!deg[i]) Q.push (i);
}
while (!Q.empty ()) {
int u = Q.front (); Q.pop ();
ret = max (ret, cnt[u]);
for (int i=; i<G[u].size (); ++i) {
int v = G[u][i];
cnt[v] += cnt[u];
if (!(--deg[v])) Q.push (v);
}
}
return ret;
} int main(void) {
//freopen ("J.in", "r", stdin); while (scanf ("%d", &n) == ) {
for (int i=; i<=n; ++i) scanf ("%d", &w[i]);
for (int i=; i<=n; ++i) G[i].clear ();
memset (deg, , sizeof (deg));
for (int i=; i<=n-; ++i) {
int u, v; scanf ("%d%d", &u, &v);
if (w[u] < w[v]) swap (u, v);
G[u].push_back (v); deg[v]++;
}
printf ("%d\n", BFS ());
} return ;
}
BFS 标程做法