我就是个萨比。。
强行增加难度。。
有点最小树形图的 什么什么 (雾
五环的猪牛算法(逃
其实并不复杂。
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
using namespace std;
int n,m,h[100010],u,v;
struct edge {
int u,v,next,H;
LL w;
bool operator < (const edge &b)const {
if(H == b.H)
return w < b.w;
return H > b.H;
}
}e[2000010];
int cnt,head[100010];
int father[100010];
bool vis[100010];
queue<int>q;
int read_int () {
char c = getchar();
int re = 0;
for(;c > '9' || c < '0';c = getchar());
for(;c >= '0' && c <= '9';c = getchar())
re = re * 10 + c - '0';
return re;
}
int find (int u) {
if(father[u] == u)
return u;
return father[u] = find(father[u]);
}
void adde (int u,int v,int w) {
e[++cnt].v = v;
e[cnt].w = w;
e[cnt].u = u;
e[cnt].H = h[v];
e[cnt].next = head[u];
head[u] = cnt;
}
int main () {
memset(head,-1,sizeof head);
n = read_int();
m = read_int();
for(int i = 1;i <= n;++i) {
h[i] = read_int();
father[i] = i;
}
for(int i = 1;i <= m;++i) {
u = read_int();
v = read_int();
if(h[v] > h[u]) {
int t = u;
u = v;
v = t;
}
int hehe = read_int();
adde(u,v,hehe);
if(h[u] == h[v])
adde(v,u,hehe);
}
int num = 1;
q.push(1);
vis[1] = 1;
while(!q.empty()) {
int u = q.front();
q.pop();
for(int i = head[u];i != -1;i = e[i].next) {
int v = e[i].v;
if(vis[v])
continue;
vis[v] = 1;
++num;
q.push(v);
}
}
sort(e + 1,e + 1 + cnt);
LL ans = 0;
for(int i = 1;i <= cnt;++i) {
if(find(e[i].u) == find(e[i].v) || !(vis[e[i].v] && vis[e[i].u]))
continue;
father[find(e[i].u)] = find(e[i].v);
ans += e[i].w;
}
printf("%d %lld\n",num,ans);
}