标签:int 复杂度 选讲 sqrt WC2022 vector include 杂题 define
新年的聚会
题目描述
解法
其实用分治的思想很容易解决聚会个数的限制,我们可以枚举一个点对其他点做分治,那么询问次数是 \(O(m\log n)\),但是这样做总人数不满足条件。
关键结论:对于一个边数为 \(m\) 的图可以划分出 \(\sqrt m\) 个独立集。对于度数 \(\geq\sqrt m\) 的点可以单独划分成独立集,对于度数 \(<\sqrt m\) 的点,考虑邻接点颜色的 \(\tt mex\) 必然小于 \(\sqrt m\),所以可以根据 \(\tt mex\) 确定它的颜色(颜色就是指独立集标号)
划分独立集可以对于每一个点枚举它划分在哪个独立集中,然后用 \(\tt meeting\) 函数检验。然后我们对于枚举两个独立集,用分治的方法来确定他们的边,也就是把较大的那个集合拆成两半,然后递归下去即可,出口就是两个集合大小都为 \(1\)
复杂度显然是说不清楚的,但是上面是一个平衡复杂度的做法,如果不够放心可以在划分独立集的时候把所有点 \(\tt random\_shuffle\) 一遍。
总结
图论问题常用度数 \(\sqrt m\) 分类的方法来平衡复杂度。
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include "meeting.h"
using namespace std;
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
const int M = 1005;
int cnt=0,p[M];
vector<pii> ans;vector<int> s[M];
void cdq(int x,int y,int xl,int xr,int yl,int yr)
{
if(xr-xl<yr-yl) swap(x,y),swap(xl,yl),swap(xr,yr);
if(xl==xr && yl==yr)
{
ans.pb(mp(s[x][xl],s[y][yl]));
return ;
}
int mid=(xl+xr)>>1;vector<int> A,B;
for(int i=yl;i<=yr;i++)
A.pb(s[y][i]),B.pb(s[y][i]);
for(int i=xl;i<=xr;i++)
i<=mid?A.pb(s[x][i]):B.pb(s[x][i]);
if(!meeting(A)) cdq(x,y,xl,mid,yl,yr);
if(!meeting(B)) cdq(x,y,mid+1,xr,yl,yr);
}
vector<pii> solve(int n)
{
srand(time(0));
for(int i=0;i<n;i++) p[i]=i;
random_shuffle(p,p+n);
for(int w=0;w<n;w++)
{
int fl=0,i=p[w];
for(int j=1;j<=cnt;j++)
{
s[j].pb(i);
if(meeting(s[j])) {fl=1;break;}
s[j].pop_back();
}
if(!fl) s[++cnt].pb(i);
}
for(int i=1;i<=cnt;i++)
for(int j=i+1;j<=cnt;j++)
{
int l1=s[i].size(),l2=s[j].size();
cdq(i,j,0,l1-1,0,l2-1);
}
return ans;
}
标签:int,复杂度,选讲,sqrt,WC2022,vector,include,杂题,define 来源: https://www.cnblogs.com/C202044zxy/p/15856601.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。