题解:P14023 [ICPC 2024 Nanjing R] 社交媒体
我们把所有数对
- 初始时
x,y 都是我的好友,直接记入答案。 - 初始时只有
x 是我的好友,此时给cnt_y 加1 。cnt_y 的含义是只要选择y 就会给答案加上cnt_y 。 - 初始时
x,y 都不是我的好友,这里需要计算一个额外的贡献,对于这样的关系计数,mp_{x,y} \gets mp_{x,y}+1 。
处理后面两类增加的贡献。考虑枚举新增的第一位好友
对于与
由于第
#include<bits/stdc++.h>
using namespace std;
const int N=200010;
int T,n,m,k;
bool cmp(int a,int b){return a>b;}
unordered_map<int,int> cnt,bj,mp[N];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>T;
while(T--){
cin>>n>>m>>k;
cnt.clear();bj.clear();
for(int i=0;i<=k;i++)mp[i].clear();
for(int i=1;i<=n;i++){
int f;
cin>>f;
bj[f]=1;
}
int ans=0;
for(int i=1;i<=m;i++){
int a,b;
cin>>a>>b;
if(bj[a]&&bj[b])ans++;
else if(bj[a])cnt[b]++;
else if(bj[b])cnt[a]++;
else if(a==b)cnt[a]++;
else{
mp[a][b]++;
mp[b][a]++;
}
}
vector<int> v;
for(int i=1;i<=k;i++)
if(cnt[i]!=0)v.push_back(cnt[i]);
sort(v.begin(),v.end(),cmp);
int res=0;
for(int i=1;i<=k;i++){//新增的第一位好友
if(bj[i])continue;
if(!v.empty()){
if(cnt[i]==v[0]){
if(v.size()>=2)res=max(res,cnt[i]+v[1]);
else res=max(res,cnt[i]);
}
else res=max(res,cnt[i]+v[0]);
}
for(auto it=mp[i].begin();it!=mp[i].end();it++){
res=max(res,cnt[i]+cnt[(*it).first]+(*it).second);
}
}
cout<<ans+res<<'\n';
}
return 0;
}