这题我一看就感觉是最小生成树的板子题
然后开心的复制板子改一下输出 过了样例 提交然后就是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;
}

京公网安备 11010502036488号