1. 程式人生 > >bnu 51643 Cactus Exploration(圖論+一元二次方程最值)(北師16校賽)

bnu 51643 Cactus Exploration(圖論+一元二次方程最值)(北師16校賽)

很久以前,whalyzh同學去沙漠旅行,看到了很多很多的仙人掌,

但是現在whalyzh同學已經想不起來最酷炫的那棵仙人掌長什麼樣了,只記得一些特徵。

小Q同學根據whalyzh同學的描述,發現這棵仙人掌可以畫成一個無向的連通圖,這個圖不存在自環,且任意一條邊至多屬於一個簡單環。所謂簡單環,是指在圖中任取一個頂點作為起點,沿著不重複的邊、經過不重複的點再次走到起點的閉合路徑。定義一棵仙人掌的酷炫程度為這棵仙人掌對應的圖中簡單環的長度最大值乘以簡單環的長度最小值,如果沒有環,則酷炫程度為0。

現在whalyzh同學還記得這棵仙人掌的頂點數n和邊數m,你需要所有滿足條件的仙人掌的酷炫程度的最大值。

Input

第一行是一個正整數T(\leq 100000),表示測試資料的組數,

每組測試資料只有一行,包含兩個整數n(2 \leq n \leq1000000000),m(0\leq m \leq 2000000000),表示仙人掌的頂點數和邊數。

Output

對於每組測試資料,輸出一個整數,表示仙人掌的酷炫程度的最大值,如果不存在滿足條件的仙人掌,請輸出-1。

Sample Input

4
2 0
2 1
2 2
2 3

Sample Output

-1
0
4
-1

Hint

對於第二組樣例,滿足條件的仙人掌只有一種,且無環,故酷炫程度的最大值為0。

對於第三組樣例,滿足條件的仙人掌只有一種,且只有一個長為2的簡單環,故酷炫程度的最大值為4。

Source

Author

quailty 題目大意:

        無向連通無自環且每一邊至多屬於一個簡單環(‘至多‘說明可以不在環上)的圖叫仙人掌,定義一棵仙人掌的酷炫程度為這棵仙人掌對應的圖中簡單環的長度最大值乘以簡單環的長度最小值,如果沒有環,則酷炫程度為0。

        仙人掌的頂點數n和邊數m,求滿足條件的仙人掌的酷炫程度的最大值

解題思路:

        分為幾種情況:

        m小於n-1則無法連通,不能算是仙人掌,輸出-1。

        m==n-1恰好是一棵樹,但是沒有簡單環,輸出0,

        m==n 可以形成一個環,長度為n,既為最大也為最小,輸出n*n

        之後考慮m>n時的仙人掌,最優解的圖中所有邊一定都是在某個環上的,因為如果不是的話,可以把這條邊加到環裡,仍然是仙人掌,答案會更優。同時考慮到圖中環的個數,加一個邊就會多一個環(構造試出來可以),所以環的個數為m-n+1,發現加邊加到2*n-2就沒法再加了(變成菊花圖)所以m>2*n-2輸出-1.,

        然後環數有了,邊數m有了,就把邊分配給每個環,可以證明有最優解裡除了最大環剩下的環的長度是一樣的,因為如果有不一樣的可以新增到最大環上答案更優,所以設最小環長度為x,f(x)=x*(m-(m-n+1-1)x) (x>=2&&x<=m/(m-n+1))  要求的就是f(x)max,找到對稱軸,帶進去算即可,注意對稱軸兩側的整數都可能是解。

#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
ll n, m;
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%lld %lld", &n, &m);
		if (m < n - 1 || m>2 * n - 2)printf("-1\n");
		else if (m == n - 1)printf("0\n");
		else if (m == n)printf("%lld\n", 1ll*n*n);
		else
		{
			ll p = m / (2 * (m - n)),tem=0;//別忘初始化,之後的那個if不一定會進去
			if (p > 1&&p<= m/(m-n))tem = p*m - (m - n)*p*p;//?
			p++;
			if (p<=m/(m-n))tem = max(tem, p*m-(m - n)*p*p);
			printf("%lld\n", tem);
		}
	}
}