原题链接:
HDU-6090
大意:
多组样例,给出图的边和顶点数,求
∑ni=1∑nj=1dist(i,j)
dist(i,j)
表示路径长度,边权值为 1 .若两点不连通,则路径长度为 n 。
思路:
贪心地考虑添加边,最优情形是一个菊花形,两点间路径为 1或 2
① 边如果太少,那么有一部分点为孤立点,额外计算。
② 边如果多了,每次添加边就是有一条路径长度 从 2 变为 1
考虑边大于完全连通图的边数,注意处理。
代码实现:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mem(s,t) memset(s,t,sizeof(s))
#define D(v) cout<<#v<<" "<<v<<endl
#define inf 0x3f3f3f3f
//#define LOCAL
inline void read(ll &x){
x=0;char p=getchar();
while(!(p<='9'&&p>='0'))p=getchar();
while(p<='9'&&p>='0')x*=10,x+=p-48,p=getchar();
}
const ll N =1e5+10;
ll a[N];
int main() {
#ifdef LOCAL
freopen("1006.in","r",stdin);
freopen("out.txt","w",stdout);
#endif
ll t;
read(t);
while(t--){
ll n,m;
read(n);read(m);
ll ans=0;
if(n-1>=m){
ll N=m+1;
ans=2*(n-N)*N*n;ans+=(n-N)*(n-N-1)*n;
ans+=2*(N-1)+2*(N-1)*(N-2);
}else if(n-1<m){
m=min((n-1)*n/2,m);
ll N=n;
ans=2*(N-1)+2*(N-1)*(N-2);
ans-=2*(m-(n-1));
}
printf("%lld\n",ans);
}
return 0;
}