本题中a180285的时间胶囊操作其实相当于随意的去走一个树形的结构。那么很容易就想到了最小生成树算法。
但是由于本题中必须从高度高的向高度低的去走。而且图是一个有向图,所以在这里克鲁斯卡尔算法不适用,因为克鲁斯卡尔算法的加边方式不会去在乎单向边的问题。
那么使用prime算法,但是优先队列的条件要稍作改变,由于题目中要求经过景点的数量尽量多为第一优先级。那么就需要首先按照高度进行排序,贪心的去走那个较高的点。
然后才是距离的限制。
#include <bits/stdc++.h>

using namespace std;
#define int long long
const int maxn = 1e7+10;
const int maxm = 1e7+10;
struct sy{
    int next;
    int to;
    int w;
} edge[maxm];
int head[maxn];
int cnt = 0;
int n, m;
int num = 0, cont = 0;
int h[maxn], dist[maxn];
bool vis[maxn];
struct Node{
    int number;
    int val;
    int h;
    bool operator < (const Node& n) const
    {
        if (h==n.h)
            return val>n.val;
        else
            return h<n.h;
    }
};
priority_queue<Node> pq;
void add_edge(int u, int v, int w)
{
    edge[++cnt].next = head[u];
    edge[cnt].to = v;
    edge[cnt].w = w;
    head[u] = cnt;
}

void init()
{
    memset(dist, 127, sizeof dist);
    memset(vis, 0, sizeof vis);
}

void prime(int bg)
{
    pq.push({bg, 0, h[bg]});
    dist[bg] = 0;
    while (pq.size())
    {
        int number = pq.top().number;
        int temp = pq.top().val;
        pq.pop();
        if (vis[number]) continue;
        num += temp;
        vis[number] = true;
        cont++;
        for (int i=head[number];~i;i=edge[i].next)
        {
//             cout<<"i="<<i<<endl;
            int next = edge[i].to;
            int w = edge[i].w;
//             cout<<"next="<<next<<" w="<<w<<endl;
            if (vis[next]) continue;
            if (dist[next]>w)
            {
//                 dist[next] = w;
                pq.push({next, w, h[next]});
            }
        }
    }
}

signed main()
{
    memset(head, -1, sizeof head);
    int u, v, w;
    cin>>n>>m;
    for (int i=1;i<=n;i++)
    {
        cin>>h[i];
    }
    for (int i=1;i<=m;i++)
    {
        cin>>u>>v>>w;
        if (h[u]>=h[v])
            add_edge(u, v, w);
        if (h[u]<=h[v])
            add_edge(v, u, w);
    }
    //每一个点为起点去求一个有向图的最小生成树,使用prime算法进行计算。
    init();
    prime(1);
    cout<<cont<<" "<<num;
    return 0;
}