二维最小乘积生成树模板
曾经的博客:
https://blog.csdn.net/cold_chair/article/details/77200459
板题:
https://www.luogu.com.cn/problem/P5540
Code:
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i < _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;
const int N = 10005;
int n, m;
struct nod {
int u, v;
int x, y, w1, w2;
} a[N];
struct P {
int x, y;
P(int _x = 0, int _y = 0) {
x = _x, y = _y;
}
};
int cmp(nod a, nod b) {
return a.w1 == b.w1 ? a.w2 < b.w2 : a.w1 < b.w1;
}
int f[N];
int F(int x) { return f[x] == x ? x : (f[x] = F(f[x]));}
int cho[N];
int ans = 1e9, ans1, ans2;
P kk() {
sort(a + 1, a + m + 1, cmp);
fo(i, 1, n) f[i] = i;
P s = P(0, 0);
int se = 0;
fo(i, 1, m) {
if(F(a[i].u) != F(a[i].v)) {
cho[i] = 1;
f[f[a[i].u]] = f[a[i].v];
s.x += a[i].x;
s.y += a[i].y;
} else cho[i] = 0;
}
if(s.x * s.y < ans || (s.x * s.y == ans && s.x < ans1)) {
ans = s.x * s.y;
ans1 = s.x; ans2 = s.y;
}
return s;
}
void dg(int x1, int y1, int x2, int y2) {
if(x1 == y1 && x2 == y2) return;
fo(i, 1, m) {
a[i].w1 = -((y2 - y1) * a[i].x + (x1 - x2) * a[i].y);
a[i].w2 = 0;
}
P p = kk();
int x3 = p.x, y3 = p.y;
if((x2 - x3) * (y1 - y3) - (y2 - y3) * (x1 - x3) <= 0) return;
dg(x1, y1, x3, y3);
dg(x3, y3, x2, y2);
}
int main() {
scanf("%d %d", &n, &m);
fo(i, 1, m) {
scanf("%d %d %d %d", &a[i].u, &a[i].v, &a[i].x, &a[i].y);
a[i].u ++, a[i].v ++;
}
fo(i, 1, m) {
a[i].w1 = a[i].x;
a[i].w2 = a[i].y;
}
P st = kk();
fo(i, 1, m) {
a[i].w1 = a[i].y;
a[i].w2 = a[i].x;
}
P en = kk();
dg(st.x, st.y, en.x, en.y);
pp("%d %d\n", ans1, ans2);
}
转载注意标注出处:
转自Cold_Chair的博客+原博客地址