CF76A
最小生成树妙题。
观察一下数据范围,
从暴力谈起,先按
但是这样复杂度是
此时找性质:有些边由于不优被放弃后,就不会成为树边了。因为最小生成树随着加边只会更优,如果之前都不在里面了,那么之后如果要用它,为什么不用原先更优秀的那个呢?
然后就可以把边的数量降至
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 5e5+10;
int n,m,G,S,c;
struct Nd{
int x,y,g,s;
}a[N],b[N];
int f[N];
int fi(int x) {
return f[x] == x ? f[x] : f[x] = fi(f[x]);
}
int cnt;
int ans = LONG_LONG_MAX;
void klska(int i) {
// });
long long p = 0; cnt = 0;
for(int i=1;i<=n;i++) f[i] = i;
for(int i=1;i<=c;i++) {
int fx = fi(a[i].x), fy = fi(a[i].y);
if(fx == fy) continue;
f[fx] = fy; p=max(p,a[i].s); a[++cnt] = a[i];
}
c = cnt;
if(cnt == n-1) {
ans = min(ans,p*S+b[i].g*G);
}
}
signed main() {
cin>>n>>m>>G>>S;
for(int i=1;i<=m;i++) {
cin>>b[i].x>>b[i].y>>b[i].g>>b[i].s;
}
sort(b+1,b+m+1,[](Nd x,Nd y) {
return x.g<y.g;
});
for(int i=1;i<=m;i++) {
int p = c+1;
while(p-1>0 && b[i].s<a[p-1].s) {
a[p]=a[p-1];
p--;
}
c++;
a[p] = b[i];
klska(i);
}
if(ans>4e18) cout<<-1;
else
cout<<ans;
return 0;
}
本文作者:cjrqwq
本文链接:https://www.cnblogs.com/yfzqwq/p/18492763
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】