Parametric MST(贪心)

本文探讨了一个涉及完全图和动态边权的参数化最小生成树问题,通过对节点权重进行排序并利用前缀和技巧,提出了求解最小生成树代价随参数变化规律的有效算法。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

Parametric MST

[Link](Problem - F - Codeforces)

题意

​ 给你一个 n n n个结点的完全图,第 i i i个点的权重为 a i a_i ai,对于任意两个点的边权 w i , j ( t ) = a i a j + t ( a i + a j ) w_{i,j}(t)=a_ia_j+t(a_i+a_j) wi,j(t)=aiaj+t(ai+aj),其中 t t t是任意一个实数, f ( t ) 是 最 小 生 成 树 的 花 费 f(t)是最小生成树的花费 f(t),问你 f ( t ) f(t) f(t)最小可能是多少。

思路

​ 首先将 a a a从小到大排序,设 s s s a a a的前缀和,对于 t t t非常大,则权值取决于 ( a i + a j ) t (a_i+a_j)t (ai+aj)t,则此时权值为 ( a 1 ∗ ( n − 1 ) + s n − s 1 ) t (a_1*(n-1)+s_n-s_1)t (a1(n1)+sns1)t,若 ( a 1 ∗ ( n − 1 ) + s n − s 1 ) > 0 (a_1*(n-1)+s_n-s_1)>0 (a1(n1)+sns1)>0则为 I N F INF INF,同理若 t t t是非常小的负数,若 ( a 1 ∗ ( n − 1 ) + s n − s 1 ) < 0 (a_1*(n-1)+s_n-s_1)<0 (a1(n1)+sns1)<0则为 I N F INF INF

​ 其它情况我们观察一下式子 w i , j ( t ) = a i a j + t ( a i + a j ) = ( a i + t ) ( a j + t ) − t 2 w_{i,j}(t)=a_ia_j+t(a_i+a_j)=(a_i+t)(a_j+t)-t^2 wi,j(t)=aiaj+t(ai+aj)=(ai+t)(aj+t)t2,令 b i = a i + t b_i=a_i+t bi=ai+t,则权值为 w i , j ( t ) = b i b j − t 2 w_{i,j}(t)=b_ib_j-t^2 wi,j(t)=bibjt2,令 w i , j = b i b j w_{i,j}=b_ib_j wi,j=bibj f ( t ) = m s t − ( n − 1 ) t 2 f(t)=mst-(n-1)t^2 f(t)=mst(n1)t2,对于所有的对于任意一个 t t t,一定满足 [ 1 , i ]   b i < 0 [1,i]\ b_i<0 [1,i] bi<0 [ i + 1 , n ]   b i > 0 [i+1,n]\ b_i>0 [i+1,n] bi>0,对于 b i < 0 b_i<0 bi<0我们将其和 m a x ( b i ) max(b_i) max(bi)相连,对于 b i > 0 b_i>0 bi>0我们将其和 m i n ( b i ) min(b_i) min(bi)相连,这样求出来的就是最小值,通过枚举 t t t求解即可

Code

#include <bits/stdc++.h>
#define x first
#define y second
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long double ld;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef unsigned long long ULL;
const int N = 2e5 + 10, M = 2 * N, INF = 0x3f3f3f3f, mod = 1e9 + 7;
const double eps = 1e-8, pi = acos(-1), inf = 1e20;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int h[N], e[M], ne[M], w[M], idx;
void add(int a, int b, int v = 0) {
    e[idx] = b, w[idx] = v, ne[idx] = h[a], h[a] = idx ++;
}
int n, m, k;
LL a[N], sum[N];
int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    int T;
    cin >> T;
    while (T -- ) {
        cin >> n;
        for (int i = 1; i <= n; i ++) cin >> a[i];
        sort(a + 1, a + 1 + n);
    for (int i = 1; i <= n; i ++) sum[i] = sum[i - 1] + a[i];
        if (sum[n] - sum[1] + a[1] * (n - 1) > 0 || 
            sum[n - 1] + a[n] * (n - 1) < 0) {
                cout << "INF\n";
                continue ;
            }

        LL res = -1e18;
        for (int i = 1; i <= n; i ++) {
            LL t = -a[i];
            LL mx = a[n] + t, mn = a[1] + t;
            LL ls = sum[i] + i * t, rs = sum[n] - sum[i] + (n - i) * t;

            res = max(res, ls * mx + rs * mn - mn * mx - (n - 1) * t * t);
        }

        cout << res << '\n';                    
    }
    return 0;
}

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值