#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 +10;
int n, m, a[N], fa[N], dp[N];
vector<int> g[N]; //邻接表
vector<pair<int, int> > edges; //存原始边


int find(int x)
{
    if(fa[x] != x) fa[x] = find(fa[x]);
    return fa[x];
}
bool cmp(int x, int y)
{
    return a[find(x)] < a[find(y)];
}


void merge(int u, int v)
{
    int fu = find(u), fv = find(v);
    if(fu != fv) fa[fv] = fu;
}

int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
        fa[i] = i;
    }

    //缩点
    for(int i = 0; i < m; i++)
    {
        int u, v;
        cin >> u >> v;
        edges.push_back({u, v});
        if(a[u] == a[v]) merge(u, v);
    }

    //建图
    for(auto [u, v] : edges) {
        int fu = find(u), fv = find(v);
        if(a[fu] < a[fv]) g[fu].push_back(fv);
        else if(a[fu] > a[fv]) g[fv].push_back(fu);
    }

    memset(dp, -1, sizeof dp);
    dp[find(1)] = 1; //此时起点价值初始化为1

    //dp的顺序
    vector<int> nodes;
    for(int i = 1; i <= n; i++) nodes.push_back(i);
    sort(nodes.begin(), nodes.end(), cmp);

    for(int u : nodes) {
        int fu = find(u);
        if(dp[fu] == -1) continue;

        for(int v : g[fu]) {
            int fv = find(v);
            if(a[fu] < a[fv]) dp[fv] = max(dp[fv], dp[fu] + 1);
            else dp[fv] = max(dp[fv], dp[fu]);
        }
    }

    cout << max(0, dp[find(n)]) << endl;
    return 0;
}

/*
1.经过缩点后:DAG图
2.有了拓扑序 A B C D E
以第i个点为终点的最大价值 f[i]

f[i]: 表示从顶点1到节点i的最大价值
v -> u
a[v] = a[u]: f[u] = max(f[v], f[u])
a[v] < a[u]: f[u] = max(f[u], f[v] + 1)
*/

0 条评论

目前还没有评论...