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;
}
posted @ 2021-08-11 21:13  fhq_treap  阅读(36)  评论(0编辑  收藏  举报