1 条题解
-
0
决定小团体强度的值有两个:
- 团体内的最小度。
- 团体人数。
我们可以考虑枚举最小度求最大的团体人数。
我们发现小于原图最小度的度肯定不优,因为原图最小度可以直接选择包含全图使团体人数最大,这给了我们一个启发。
在之后,由于我们要增大团体内的最小度,所以最小度的点不会被包含,因此可以考虑删掉这些点。
这个时候问题由变回了原样,我们可以继续找最小度的点,如此类推。
注意到动态删点加维护连通块大小不好做,但是动态维护点的度数不难,我们先利用
set维护删点顺序,再倒着加点,变成动态加点维护连通块大小,并查集即可维护。#include<bits/stdc++.h> #define LL long long using namespace std; const LL N=3e5+5; LL n,m,x,y,ans,fa[N],a[N],du[N],d[N],sz[N],vis[N]; vector<LL>v[N]; stack<LL>s; set<pair<LL,LL>>p; LL find(LL x) { if(fa[x]==x)return x; return fa[x]=find(fa[x]); } int main() { scanf("%lld%lld",&n,&m); for(int i=1;i<=n;i++)fa[i]=i,a[i]=i,sz[i]=1; for(int i=1;i<=m;i++) { scanf("%lld%lld",&x,&y); v[x].push_back(y); v[y].push_back(x); du[x]++,du[y]++; } for(int i=1;i<=n;i++) { p.insert({du[i],i}); } while(!p.empty()) { LL t=(*p.begin()).second; p.erase(p.begin()); s.push(t); d[t]=du[t]; for(LL i:v[t]) { if(d[i])continue; p.erase(p.lower_bound({du[i],i})); du[i]--; p.insert({du[i],i}); } } for(int i=1;i<=n;i++) { LL t=s.top(); vis[t]=1; s.pop(); for(LL j:v[t]) { if(vis[j]==0)continue; LL fx=find(t),fy=find(j); if(fx!=fy) { fa[fx]=fy; sz[fy]+=sz[fx]; } } ans=max(ans,sz[find(t)]*d[t]); } printf("%lld",ans); return 0; }
- 1
信息
- ID
- 7608
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 15
- 已通过
- 6
- 上传者