题目:构造一个<=75个点的图,使得大小为4的团恰有k个。(k<=1e6)
思路:(官方题解)自己写的只过了百分之七十数据。。。
•构造一个大小为t的完全图,和a, b, c, d, e五个点。
•a, b, c, d, e五个点之间没有边,他们只会向t个点连边。
•如果连了x个,构成C(x, 3)个大小为4个团。
•找到最大的t,枚举a,b,c,d,计算e。
#include <bits/stdc++.h>
using namespace std;
struct fuck{
int x,y;
fuck(int _x,int _y)
{
x=_x;
y=_y;
}
};
vector<fuck>a;
int n,kk,m,p[77],c[77],book[75*75*75];
int nu[77];
int main()
{
for(int i=4;i<=75;i++)
p[i]=i*(i-1)*(i-2)*(i-3)/24;
book[0]=2;
c[2]=0;
for(int i=3;i<=75;i++)
{
c[i]=i*(i-1)*(i-2)/6;
book[c[i]]=i;
}
scanf("%d",&kk);
int kt=0;
for(int i=70;i>=4;i--)
if(p[i]<=kk)
{
kt=i;
break;
}
for(int i=1;i<=kt;i++)
{
for(int j=i+1;j<=kt;j++)
a.push_back(fuck(i,j));
}
kk-=p[kt];
int flag=0;
for(int i=2;i<=kt;i++)
if(!flag)
for(int j=2;j<=kt;j++)
if(!flag)
for(int k=2;k<=kt;k++)
if(!flag)
for(int l=2;l<=kt;l++)
if(!flag)
{
int r=kk-c[i]-c[j]-c[k]-c[l];
if(r>=0&&book[r]&&book[r]<=kt)//必须要加book[r]<=kt判断!可能会用到kt以外的点。。。
{
nu[1]=i;
nu[2]=j;
nu[3]=k;
nu[4]=l;
nu[5]=book[r];
flag=1;
}
}
for(int i=1;i<=5;i++)
if(nu[i]>=3)
{
kt++;
for(int j=1;j<=nu[i];j++)
a.push_back(fuck(kt,j));
}
printf("%d %d\n",kt,a.size());
for(int i=0;i<a.size();i++)
printf("%d %d\n",a[i].x,a[i].y);
return 0;
}