题目链接
题目大意:
给定从1开始到n个点之间的距离数组d,让你构造一个图使得总权重最小(可加负权边)
题目分析:
分析样例可以得知相邻点的权重对答案总贡献一定为0,即隔点才会产生贡献,举个例子,如果n为5,那么答案就会是3->1
4->1 5->1 4->2 5->2 5->3 权重和取负,这里可以发现节点编号越大出现次数越多对答案贡献越多,这里我们考虑从小到大排序从而保证结果最优,注意计算权重我们可以用前缀和数组进行计算。
代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define pf push_front
#define int long long
#define debug(x) std::cerr << #x << " = " << (x) << std::endl
#define fast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
typedef set<int>::iterator SIT;
int dx[]={0,-1,0,1},dy[]={-1,0,1,0};
int gcd(int a,int b) {return b?gcd(b,a%b):a;}
int lcm(int a,int b) {return a/gcd(a,b)*b;}
const double eps=1e-6;
const int INF=0x3f3f3f3f,mod=998244353;
const int N=1e6+10;
int a[N],sum[N];
int n;
signed main(){
fast;
int T;
cin>>T;
while(T--){
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+a[i];
int ans=0;
for(int i=3;i<=n;i++)
ans+=(i-2)*a[i]-sum[i-2];
printf("%lld\n",-ans);
}
return 0;
}