CodeForces - 76A Gift (两个取值方向的最小生成树)

gThe kingdom of Olympia consists of N cities and M bidirectional roads. Each road connects exactly two cities and two cities can be connected with more than one road. Also it possible that some roads connect city with itself making a loop.

All roads are constantly plundered with bandits. After a while bandits became bored of wasting time in road robberies, so they suggested the king of Olympia to pay off. According to the offer, bandits want to get a gift consisted of gold and silver coins. Offer also contains a list of restrictions: for each road it is known gi — the smallest amount of gold and si — the smallest amount of silver coins that should be in the gift to stop robberies on the road. That is, if the gift contains agold and b silver coins, then bandits will stop robberies on all the roads that gi ≤ a and si ≤ b.

Unfortunately kingdom treasury doesn't contain neither gold nor silver coins, but there are Olympian tugriks in it. The cost of one gold coin in tugriks is G, and the cost of one silver coin in tugriks is S. King really wants to send bandits such gift that for any two cities there will exist a safe path between them. Your task is to find the minimal cost in Olympian tugriks of the required gift.

Input

The first line of the input contains two integers N and M (2 ≤ N ≤ 200, 1 ≤ M ≤ 50 000) — the number of cities and the number of roads, respectively. The second line contains two integers G and S (1 ≤ G, S ≤ 109) — the prices of gold and silver coins in tugriks. The following M lines contain information about the offer. Each of the records in list is given as four integers xi, yi, gi, si, where xi and yi are the numbers of cities that the road connects and gisi are minimal gold and silver coins requirements for the i-th road (1 ≤ xi, yi ≤ N, 1 ≤ gi, si ≤ 109). Cities are numbered from 1 to N. It is possible that there are more than one road between a pair of cities. It is possible that a road connects the city with itself.

Output

The output should contain the minimal cost of the gift in Olympian tugriks. If there is no gift that satisfies the given requirements output .g

Examples

Input

3 3
2 1
1 2 10 15
1 2 4 20
1 3 5 1

Output

30

 

               一堆边,求取最小生成树,树的价值为边中最大的g需求量*g单价+边中最大的s需求量*s单价。

               这样我们按照g从小到大排序,之后按s从小到大排序。这样我们枚举每一条边作为参考,将加上(考虑上)这条边后(不一定在形成的树里面)最小的形成树价格与ans不断对比,最后输出答案。 

               在其他博客中我们可以了解到,对于加上此条边后的形成树一定是在(考虑上此条边和(考虑上上条边后形成的最小树的边))中形成的。我们可以假设:在添加x边的时候,第T边价值为a1,在添加x+1边的时候,价值为a2;在添加x边的时候,第K价值为b1,在添加x+1边的时候,价值为b2.假设T和K的添加x边的时候作用相同,但是a1<=b1,那么T当选。在此条件下,添加x+1假设导致添加后K边效率却比T好,我们可以得出b2<a2。但是我们可以看出一条边的价值要不是0就是ed[i].g*g或者ed[i].s*s或者ed[i].g*g+ed[i].s*s;我们可以得知,在添加x+1边的时候,最新的边需求g一定是最大的,那么影响其他边价值变化的只有需求s。所以要么a1=b1=0,要么a1=0,b1=需求s*s单价(也就是此时K边的需求s为最大需求量s),在这种情况下a2也只能是0,所以b2<a2的情况不存在。所以我们的想法应该正确撒~(有逻辑问题欢迎指出!)。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 50005;
int n, m; ll g, s;
int fa[205];
struct fuck {
	int u, v;
	ll g, s;
}ed[maxn];
int fin(int x) {
	if (x != fa[x]) {
		fa[x] = fin(fa[x]);
	}
	return fa[x];
}
bool cmp(fuck a, fuck b) {
	if (a.g != b.g) {
		return a.g < b.g;
	}
	return a.s < b.s;
}
bool cmp1(int a, int b) {
	return ed[a].s < ed[b].s;
}
void init() {
	for (int i = 1; i <= n; i++)
		fa[i] = i;
}
fuck sta[205];
int main() {
	ios::sync_with_stdio(0);
	cin >> n >> m >> g >> s;
	for (int i = 0; i < m; i++) {
		cin >> ed[i].u >> ed[i].v >> ed[i].g >> ed[i].s;
	}
	sort(ed, ed + m, cmp);
	memset(sta, -1, sizeof sta);
	long long ans = 0x3f3f3f3f3f3f3f3f; int len = 0;
	for (int i = 0; i < m; i++) {
		init();
		sta[len] = ed[i];
		for (int j = len; j > 0; j--) {
			if (sta[j].s < sta[j - 1].s)
				swap(sta[j], sta[j - 1]);
		}
		int sum = 0;
		for (int j = 0; j <= len; j++) {
			int a = fin(sta[j].u);
			int b = fin(sta[j].v);
			if (a != b) {
				sta[sum++] = sta[j];
				fa[a] = b;
			}
		}
		if (sum == n - 1) {
			ans = min(ans, ed[i].g*g + sta[sum - 1].s*s);
		}
		len = sum;
	}
	if (ans == 0x3f3f3f3f3f3f3f3f) {
		cout << "-1\n";
	}
	else 
		cout << ans << "\n";
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值