HDU - 6090 - Rikka with Graph

Rikka with Graph

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 121    Accepted Submission(s): 86


Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

For an undirected graph  G  with  n  nodes and  m  edges, we can define the distance between  (i,j)  ( dist(i,j) ) as the length of the shortest path between  i  and  j . The length of a path is equal to the number of the edges on it. Specially, if there are no path between  i  and  j , we make  dist(i,j)  equal to  n .

Then, we can define the weight of the graph  G  ( wG ) as  ni=1nj=1dist(i,j) .

Now, Yuta has  n  nodes, and he wants to choose no more than  m  pairs of nodes  (i,j)(ij)  and then link edges between each pair. In this way, he can get an undirected graph  G  with  n  nodes and no more than  m  edges.

Yuta wants to know the minimal value of  wG .

It is too difficult for Rikka. Can you help her?  

In the sample, Yuta can choose  (1,2),(1,4),(2,4),(2,3),(3,4) .
 

Input
The first line contains a number  t(1t10) , the number of the testcases. 

For each testcase, the first line contains two numbers  n,m(1n106,1m1012) .
 

Output
For each testcase, print a single line with a single number -- the answer.
 

Sample Input
  
  
1 4 5
 

Sample Output
  
  
14
 

Source
 

官方题解:

考虑贪心地一条一条边添加进去。

当 m≤n−1mn1 时,我们需要最小化距离为 nn 的点对数,所以肯定是连出一个大小为 m+1m+1 的联通块,剩下的点都是孤立点。在这个联通块中,为了最小化内部的距离和,肯定是连成一个菊花的形状,即一个点和剩下所有点直接相邻。

当 m>n−1m>n1 时,肯定先用最开始 n−1n1 条边连成一个菊花,这时任意两点之间距离的最大值是 22。因此剩下的每一条边唯一的作用就是将一对点的距离缩减为 11

这样我们就能知道了最终图的形状了,稍加计算就能得到答案。要注意 mm 有可能大于 n(n−1)22n(n1)

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
#define LL long long
LL t,n,m;
int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld%lld",&n,&m);
        if(m>=n*(n-1)/2)
            printf("%lld\n",n*(n-1));//每个点到另一点都是距离为1
        else if(m>=n-1)
        {
            LL more = m - n + 1;//将所有点连通后多出的边数
            printf("%lld\n",2*((n-1)*(n-1) - more));  //2*(n-1)^2就是使用n-1条边将所有点连起来后所有两点距离之和
        }
        else
        {
            LL out = n - m - 1;//out表示未能连入图中的点的个数
            LL ans = 2*(n-out-1)*(n-out-1)+n*out*(n-out)+n*(n-1)*out;//n-out为连通的点的个数
            //ans = 连通的点之间的距离总和(双向,所以*2)+ 连通图内各点连到连通图外各点的边的总数*n(单向,从内连到外)+ 图外各点连到其余所有点的变数之和*n(单向,从图外一点出发)
            printf("%lld\n",ans);
        }
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值