参考别人的blog:点击打开链接
看这里
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <ctime>
#include <functional>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
#define eps 1e-10
#define inf 0x3f3f3f3f
#define LL long long
#define pii pair<int, int>
#define MP make_pair
#define md (ll + rr >> 1)
#define ls i << 1
#define rs ls | 1
#define lson ll, md, ls
#define rson md + 1, rr, rs
#define N 100010
#define M 400020
struct edge{
int u, v, c, t, w;
void input(){
scanf("%d%d%d%d", &u, &v, &c, &t);
}
bool operator < (const edge &b) const {
return w < b.w;
}
};
struct point{
int x, y;
point(int x = 0, int y = 0) : x(x), y(y) {}
point operator - (const point &b) const {
return point(x - b.x, y - b.y);
}
};
LL cross(point a, point b){
return 1LL * a.x * b.y - 1LL * a.y * b.x;
}
edge ee[N];
int ansx, ansy, n, m, fa[N];
int find(int x){
if(fa[x] != x) fa[x] = find(fa[x]);
return fa[x];
}
point Kruska(){
int sx = 0, sy = 0;
sort(ee, ee + m);
for(int i = 0; i <= n; ++i) fa[i] = i;
for(int i = 0; i < m; ++i){
int u = ee[i].u, v = ee[i].v;
if(find(u) == find(v)) continue;
fa[find(u)] = find(v);
sx += ee[i].c;
sy += ee[i].t;
}
LL sum = 1LL * sx * sy, ans = 1LL * ansx * ansy;
if(sum < ans || sum == ans && sx < ansx)
ansx = sx, ansy = sy;
return point(sx, sy);
}
void solve(point A, point B){
for(int i = 0; i < m; ++i){
ee[i].w = ee[i].t * (B.x - A.x) + ee[i].c * (A.y - B.y);
}
point C = Kruska();
if(cross(B - A, C - A) >= 0)
return ;
solve(A, C);
solve(C, B);
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 0; i < m; ++i)
ee[i].input();
ansx = inf, ansy = inf;
for(int i = 0; i < m; ++i)
ee[i].w = ee[i].c;
point A = Kruska();
for(int i = 0; i < m; ++i)
ee[i].w = ee[i].t;
point B = Kruska();
solve(A, B);
printf("%d %d\n", ansx, ansy);
return 0;
}