The 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 .

Example

Input
3 3
2 1
1 2 10 15
1 2 4 20
1 3 5 1
Output
30

  题目大意是说每条边,带两条权值g,s,给定G和S,设a为所有使用的边中g的最大值,b为所有使用的边中s的最大值,求连通n个城市的最小的(a * G + b * S)

  首先思考暴力吧,按照第一种权值给边排序,然后Kruskal乱搞,总时间复杂度$O\left(m^{2}\log m\right)$,高兴地发现这么会严重TLE。

  继续思考,二分第一种权值,然后Kruskal顶上,总时间复杂度$O\left(m\cdot \log^{2}m\right)$,看起来可以过,然而我可以举出不满足二分条件的反例。假如G值特别小,S值特别大,边数远远大于点数,一条边g值比较大,但是s值非常的小,二分的话很可能会忽略这一条边,导致答案是错的。

  继续思考人生。继续第一种思路,先按照第一种权值进行排序,考虑上一次的最小生成树,每次只会添加一条边,因此有两种方法可以在O(n)的时间内处理完。

  1. 在一棵树上添加一条边,会形成一个环,找到这个环,删去其中s值最大的一条边(由于插入的边不能被删去,这个的过程就是树上两点间的简单路径找s值最大的一条边,这个过程可以用LCT做到单次操作$O\left(\log n\right)$)。因为上一个生成树最有n个点,n - 1条边,所以时间复杂度为O(n)
  2. 用一个数组维护,然后插入排序,接着做一次最小生成树。时间复杂度仍然是O(n)

   每次生成完一棵树就更新答案就行了。

  贡献一堆WA,ans的初值不能设小了,至少(1 << 61)吧!

Code

 /**
* CodeForces
* Problem#76A
* Accepted
* Time:248ms
* Memory:2820k
*/
#include<iostream>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<ctime>
#include<map>
#include<stack>
#include<set>
#include<queue>
#include<vector>
#ifndef WIN32
#define AUTO "%lld"
#else
#define AUTO "%I64d"
#endif
using namespace std;
typedef bool boolean;
#define inf 0xfffffff
#define smin(a, b) (a) = min((a), (b))
#define smax(a, b) (a) = max((a), (b))
template<typename T>
inline boolean readInteger(T& u) {
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-' && x != -);
if(x == -) {
ungetc(x, stdin);
return false;
}
if(x == '-') {
aFlag = -;
x = getchar();
}
for(u = x - ''; isdigit((x = getchar())); u = u * + x - '');
u *= aFlag;
ungetc(x, stdin);
return true;
} typedef class union_found{
public:
int *f;
int points;
union_found():f(NULL), points() {}
union_found(int points):points(points) {
f = new int[(const int)(points + )];
}
int find(int x) {
if(f[x] != x) return f[x] = find(f[x]);
return f[x];
}
void unit(int fa, int so) {
int ffa = find(fa);
int fso = find(so);
f[fso] = ffa;
}
boolean connected(int a, int b) {
return find(a) == find(b);
}
void clear() {
for(int i = ; i <= points; i++)
f[i] = i;
}
}union_found; typedef class Edge {
public:
int from;
int end;
int g;
int s;
Edge(int from = , int end = , int g = , int s = ):from(from), end(end), g(g), s(s) { }
}Edge; int n, m;
long long G, S;
Edge* edges; inline void init() {
readInteger(n);
readInteger(m);
readInteger(G);
readInteger(S);
edges = new Edge[(const int)(m + )];
for(int i = ; i <= m; i++) {
readInteger(edges[i].from);
readInteger(edges[i].end);
readInteger(edges[i].g);
readInteger(edges[i].s);
}
} boolean cmp(const Edge& a, const Edge& b) {
if(a.g != b.g) return a.g < b.g;
return a.s < b.s;
} int top = ;
Edge *x;
union_found uf;
long long g0 = , s0 = ;
long long res = (1LL << );
inline void solve() {
x = new Edge[(const int)(n + )];
sort(edges + , edges + m + , cmp);
uf = union_found(n);
for(int i = ; i <= m; i++) {
uf.clear();
x[++top] = edges[i];
for(int j = top; j > ; j--)
if(x[j].s < x[j - ].s)
swap(x[j], x[j - ]);
g0 = , s0 = ;
int fin = ;
for(int j = ; j <= top; j++) {
if(!uf.connected(x[j].from, x[j].end)) {
x[++fin] = x[j];
smax(g0, (long long)x[j].g);
smax(s0, (long long)x[j].s);
uf.unit(x[j].from, x[j].end);
if(fin == n - ) break;
}
}
if(fin == n - )
smin(res, g0 * G + s0 * S);
top = fin;
}
if(res == (1LL << ))
printf("-1\n");
else printf(AUTO"\n", res);
} int main() {
init();
solve();
return ;
}

CodeForces 76A Gift - 最小生成树的更多相关文章

  1. CodeForces - 76A:Gift (最小生成树 解决单调性问题是思想)

    题意:给定N点M边的无向连通图,每条边有两个权值(g,s). 给定G,S. 让你给出一组(g0,s0)使得图中仅留下g<=g0, s<=s0的边之后,依然连通,并求Gg0+Ss0的最小值. ...

  2. CF76A.Gift [最小生成树]

    CF76A.Gift 题意:noi2014魔法森林弱化版QwQ,最小化\(max(g_i)*G + max(s_i)*S\)的最小生成树 考虑按g升序加边,用已在生成树中的边和新加入的边求当前最小生成 ...

  3. codeforces 1245D(最小生成树)

    题面链接:https://codeforces.com/problemset/problem/1245/D 题意大概是给你一些城市的坐标,可以在城市中建立发电站,也可以让某个城市和已经建好发电站的城市 ...

  4. CodeForces 141E: ...(最小生成树)

    [条件转换] 两两之间有且只有一条简单路径<==>树 题意:一个图中有两种边,求一棵生成树,使得这棵树中的两种边数量相等. 思路: 可以证明,当边的权是0或1时,可以生成最小生成树到最大生 ...

  5. Codeforces Educational Codeforces Round 3 B. The Best Gift 水题

    B. The Best Gift 题目连接: http://www.codeforces.com/contest/609/problem/B Description Emily's birthday ...

  6. Educational Codeforces Round 3 E. Minimum spanning tree for each edge (最小生成树+树链剖分)

    题目链接:http://codeforces.com/contest/609/problem/E 给你n个点,m条边. 问枚举每条边,问你加这条边的前提下组成生成树的权值最小的树的权值和是多少. 先求 ...

  7. 【最小生成树】Codeforces 707B Bakery

    题目链接: http://codeforces.com/problemset/problem/707/B 题目大意: 给你N个点M条无向边,其中有K个面粉站,现在一个人要在不是面粉站的点上开店,问到面 ...

  8. CF Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树变种

    题目链接:http://codeforces.com/problemset/problem/609/E 大致就是有一棵树,对于每一条边,询问包含这条边,最小的一个生成树的权值. 做法就是先求一次最小生 ...

  9. Codeforces 1120D Power Tree [最小生成树]

    洛谷 Codeforces 这题怎么一个中文题解都没有,是不是你们都认为太水了-- 思路 显然可以用dfs序把每个节点变成给一个区间的叶子节点加上某个数. 显然把叶子序列差分一下变为\(a_1,a_2 ...

随机推荐

  1. javascript 字符串去空格

    1.正则去空格 a.去掉字符串中所有空格 " hello world ".replace(/\s+/g,"");//helloworld b.去掉字符串左边空格 ...

  2. PHP AOP编程思想

    AOP思想(面向切面编程) 在应用开发中,我们经常发现需要很多功能,这些功能需要经常被分散在代码中的多个点上,但是这些点事实上跟实际业务没有任何关联.比如,在执行一些特殊任务之前需要确保用户是在登陆状 ...

  3. Kafka性能

    基准测试Apache Kafka:每秒写入2百万(在三台便宜的机器上) 核心的数据枢纽一定是高效的,可预测的,并且容易扩展.Kafka能够做到在普通的硬件上支撑每秒百万次写入. Kafka的数据模型非 ...

  4. [MySQL 5.6] MySQL 5.6 group commit 性能测试及内部实现流程

    [MySQL 5.6] MySQL 5.6 group commit 性能测试及内部实现流程 http://mysqllover.com/?p=581 尽管Mariadb以及Facebook在long ...

  5. SQLserver数据库连接问题

    可能安装好之后数据库的端口1433被防火墙拦截了,查看端口是否在监听当中: 在cmd里输入命令 :netstat -an 查看是否处在监听中,如果没有进入下面的设置, C:\Windows\SysWO ...

  6. Tesseract-OCR 训练过程 V3.02

    软件: jTessBoxEditor Version 0.9 (30 April 2013) Tesseract-OCR win32 v3.02 with Leptonica   训练步骤:   1. ...

  7. collections模块(收藏)

    collections是Python内建的一个集合模块,提供了许多有用的集合类. 1. namedtuple 我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成: >> ...

  8. Postman使用js获取日期

    在用postman进行接口自动化测试的时候,某个查询接口需要使用到日期参数进行请求: 假设当前日期为2018-05-07 10:30:20 ,需要传的日期为: beginTime:2018-05-01 ...

  9. Oracle业务用户密码过期问题的解决

    实验环境:Oracle 11.2.0.4 如果DBA不知道业务用户密码,当业务密码过期,应用要求DBA帮忙重设为原来的密码. 1.查询业务用户密码 从user$查到hash加密过的值: select ...

  10. 使用Linux工作之Fedora KDE

    小明拿着在Windows下不断蓝屏的T440和公司建议不使用云笔记的规定,心下想着,是时候回归linux了... 一.系统的获取与启动盘的制作 fedora20 KDE版 liveusb-creato ...