思路
CF 思维题。
因为我们要让边权值最小,所以可以利用贪心思想先将数组 \(d\) 进行升序排序。
然后再预处理出每一条边的权重。
其次我们来想一下如何处理答案,因为这道题说图中不能出现负环和重边,所以我们可以通过加反方向负边的方法来解决这道题。
因为对于一条边,这条边之后的所有点都会与这条边之前的点连负边,它们都会经过这条边,我们就可以把这条边之前的点数与这条边之后的点数相乘,得到所有经过这条边的负边数量。
得出核心代码。
for(int i = 2; i <= n; i++){
e[i] = d[i] - d[i - 1];
ans += e[i] * (n - i + 1) * (i - 1) - e[i];//记得加上原边的权值
}
AC 代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5+10;
int d[N],e[N],n,ans,T;
int main(){
// freopen("text.in","r",stdin);
// freopen("text.out","w",stdout);
ios::sync_with_stdio(0),cout.tie(0),cin.tie(0);
cin>>T;
while (T--){
cin>>n;
ans = 0;
for (int i = 1; i <= n; i++){
cin>>d[i];
}
sort(d + 1, d + n + 1);
for(int i = 2; i <= n; i++){
e[i] = d[i] - d[i - 1];
ans += e[i] * (n - i + 1) * (i - 1) - e[i];//记得加上原边的权值
}
cout <<-ans<< '\n';
}
return 0;
}
标签:Great,负边,int,题解,cin,Graphs,ans,条边
From: https://www.cnblogs.com/zenoszheng/p/18619978