hdu6090 Rikka with Graph

Rikka with Graph

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


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

 题目意思是说对于n个点,最多m条边的图中,求所有点i到点j的最短距离(如果不连通 距离为n)的和的最小值。
解题思路:这道题关键是找出加边的策略。假设初始状态一条边都没有,然后添加1~n-1条边时肯定时让尽可能多的点联通在一起,然后容易发现将n-1个点连在同一个点时和最小,然后发现现在距离最长的两点间的距离为2,因此每加一条边只能将一条距离为2的路变为1(i到j和j到i,需要ans-2),当加入n*(n-1)条边时任意两点间的距离都是1,达到最小值。
因此,根据m的大小,我们分三种情况求就可以了
代码如下:
#include<bits/stdc++.h>
using namespace std;
int main()
{
	std::ios::sync_with_stdio(false);
	int T;
	long long n,m,ans,tmp;
	cin>>T;
	while(T--)
	{
		cin>>n>>m;
		if(m>=(n*(n-1)/2))
		{
			cout<<n*(n-1)<<endl;
			continue;
		}
		if(m<n-1)
		{
			ans=0;
			ans+=(m*2);
			ans+=(m*(m-1)*2);
			tmp=n-1-m;
			ans+=(tmp*(tmp-1)*n);
			ans+=(tmp*(m+1)*2*n);
			cout<<ans<<endl;
			continue;
		}
		ans=0;
		ans+=((n-1)*2);
		ans+=((n-1)*(n-2)*2);
		ans-=((m-(n-1))*2);
		cout<<ans<<endl;
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/outp0st/article/details/77035656