CF76A Gift
考虑到\(n\)很小。
我们可以直接对一维排序,再以此加边。跑另一维的最小生成树。
考虑到只有组成生成树的\(n - 1\)一条边和最新加入的一条边有用。
所以我们直接\(sort\)。
复杂度\(O(m(n + nlogn))\)
#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
#define N 205
#define M 50005
ll n,m;
struct P{
int u,v,ag,au;
}e[M],used[M];
inline bool cmp1(P a,P b){return a.au < b.au;}
inline bool cmp2(P a,P b){return a.ag < b.ag;}
ll ans = 9223372036854775800;
ll w,cnt;
ll f[N];
inline ll find(ll x){return (f[x] == x) ? x : (f[x] = find(f[x]));}
ll S,G;
int main(){
scanf("%lld%lld%lld%lld",&n,&m,&S,&G);
for(int i = 1;i <= m;++i)
scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].ag,&e[i].au);
std::sort(e + 1,e + m + 1,cmp1);
for(int i = 1;i <= m;++i){
used[++w] = e[i];
std::sort(used + 1,used + w + 1,cmp2);
cnt = 0;
for(int j = 1;j <= n;++j)f[j] = j;
for(int j = 1;j <= w;++j){
ll f1 = find(used[j].u),f2 = find(used[j].v);
if(f1 == f2)continue;
f[f1] = f2;
cnt ++ ;
used[cnt] = used[j];
}
if(cnt == n - 1)
ans = std::min(ans,S * used[cnt].ag + G * e[i].au);
w = cnt;
}
if(ans == 9223372036854775800)
puts("-1");
else
std::cout<<ans<<std::endl;
return 0;
}