开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情
题目链接
题目
Doremy's new city is under construction! The city can be regarded as a simple undirected graph with n vertices. The i-th vertex has altitude . Now Doremy is deciding which pairs of vertices should be connected with edges.
Due to economic reasons, there should be no self-loops or multiple edges in the graph.
Due to safety reasons, there should not be pairwise distinct vertices u, v, and w such that and the edges (u,v) and (v,w) exist.
Under these constraints, Doremy would like to know the maximum possible number of edges in the graph. Can you help her?
Note that the constructed graph is allowed to be disconnected.
题目大意
城市可以被视为具有 个顶点的简单无向图。第 个顶点的高度为 。现在 Doremy 正在决定在哪些点对之间连边。
由于经济原因,图中不应有自环或重边。
由于安全原因,不应存在成对的不同顶点 、 和 ,使得 且边 和 同时存在。
在这些约束条件下,Doremy 希望知道图中最大可能的边数。建边后的图允许不连通。
思路
如果一个点跟和自己权值相同的点连边了,那么它们俩都不能再与其他点连边,只有当整个图所有点权全部相等时才考虑这样做,答案为 。
其他情况下,每个点只可能跟比自己小的点连边或跟比自己大的点连边。显然把点从小到大排序后,从某个位置将所有点分成两个部分,最大化两部分点的数量之积即为最优解。
代码
#include <iostream>
#include <algorithm>
#include <math.h>
#include <stdio.h>
#include <map>
#include <vector>
#include <queue>
#define nnn printf("No\n")
#define yyy printf("Yes\n")
using namespace std;
using LL=long long;
const int N=500001;
const LL mod=1000000007;
//const LL mod=998244353;
struct asdf{
};
vector<int> e[N];
int n,m,k,x,y,z,tot,a[N],b[N];
char ch;
LL gcd(LL x,LL y) {return y==0?x:gcd(y,x%y);}
LL solve()
{
scanf("%d",&n);
int flag=0;
for (int i=1;i<=n;++i)
{
scanf("%d",&a[i]);
if (a[i]!=a[1]) flag=1;
}
if (!flag) return printf("%d\n",n/2);
sort(a+1,a+1+n);
LL cnt=1,ans=0;
for (int i=2;i<=n;++i)
{
if (a[i]==a[i-1]) cnt++;
else
{
ans=max(ans,cnt*(n-cnt));
cnt++;
}
}
printf("%lld\n",ans);
// scanf("%d",&m);
// scanf("%d",&k);
}
int main()
{
int T=1;
scanf("%d",&T);
// while (T--)
// if (solve()) yyy;
// else nnn;
// while (T--) printf("%lld\n",solve());
while (T--) solve();
// solve();
return 0;
}