这题我一看就感觉是最小生成树的板子题
然后开心的复制板子改一下输出 过了样例 提交然后就是ac0% why?
在仔细看题 貌似点的高度没用 好像只能从高点滑到低点 。。。
我最小生成树只会kruscal算法貌似不能解决 开始学习prim算法
最后掏出了这个优先队列优化的prim算法(最小生成树板子
并且把优先度改成 点的高度比较第一 边长第二
#include<bits/stdc++.h> #define ll long long using namespace std; const long long inf = 1e18; const int N = 1e6 + 5; struct Edge {///链式前向星存图 int v, next; ll cost; }edge[N << 1]; int tot, head[N]; void addedge(int u, int v, ll w) { edge[tot].v = v; edge[tot].cost = w; edge[tot].next = head[u]; head[u] = tot++; } struct qnode {///优先队列优化prim算法 int v, h; ll dis; qnode(int _v = 0,int _h = 0, ll _dis = 0): v(_v), h(_h), dis(_dis){} bool operator < (const qnode &s) const {///优先度第一是点高度 其次是边长 if(h==s.h) return dis>s.dis; return h<s.h; } }; int h[N], cnt, n, m;; bool vis[N]; ll dist[N], ans; void prim() { for(int i = 1; i <= n; i++) dist[i] = inf; priority_queue<qnode> q; q.push(qnode(1, h[1], 0)); dist[1] = 0; while(!q.empty()) { qnode tmp = q.top(); q.pop(); int u = tmp.v; if(vis[u]) continue; vis[u] = 1; cnt++, ans += dist[u]; for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].v; ll cost = edge[i].cost; if(!vis[v] && dist[v] > cost) { dist[v] = cost; q.push(qnode(v, h[v], dist[v])); } } } } int main() { memset(head, -1, sizeof(head)); cin >> n >> m; for(int i = 1; i <= n; i++) cin >> h[i]; while(m--) { int u, v; ll w; cin >> u >> v >> w; if(h[u] >= h[v]) addedge(u, v, w); if(h[v] >= h[u]) addedge(v, u, w); } prim(); cout << cnt << " " << ans << endl; return 0; }