题意
构造一棵树,让它有k条直径。边权都是非负整数,要求点数不能超过5000。
$k leq 5000000$
思考
让树根底下分别挂着长度为a,b,c的边权为0的链,然后将链的某一端向根连一条边权为1的边,这样共有ab+ac+bc条直径。可以发现,对于数据范围内的k,可以很快地找到这样的a,b,c。
代码
1 // luogu-judger-enable-o2 2 // luogu-judger-enable-o2 3 // luogu-judger-enable-o2 4 // luogu-judger-enable-o2 5 #include<bits/stdc++.h> 6 using namespace std; 7 typedef unsigned int ui; 8 ui SEED; 9 int k; 10 int size,a[5555]; 11 int b[5000005]; 12 bool vis[5000005]; 13 inline int R(int l,int r) 14 { 15 SEED^=SEED<<13; 16 SEED>=SEED>>5; 17 SEED^=1; 18 return SEED%(r-l+1)+l; 19 } 20 int main() 21 { 22 // freopen("diameter.in","r",stdin); 23 // freopen("diameter.out","w",stdout); 24 ios::sync_with_stdio(false); 25 for(int i=1;i*i<=5000000;++i) 26 vis[i*i]=1; 27 cin>>k; 28 if(k<=3000) 29 { 30 cout<<k+2<<endl; 31 cout<<k+2<<" "<<1<<" "<<100<<endl; 32 for(int i=1;i<=k;++i) 33 cout<<1<<" "<<i+1<<" "<<1<<endl; 34 return 0; 35 } 36 int base=k; 37 for(int c=sqrt(base);c>=1;--c) 38 { 39 int g=k-c*c; 40 for(int a=1;a*a<=g;++a) 41 for(int b=1;b*b<=g;++b) 42 if(a*b+a*c+b*c==k) 43 { 44 --a,--b,--c; 45 cout<<a+b+c+4<<endl; 46 cout<<1<<" "<<2<<" "<<1<<endl; 47 for(int i=1;i<=a;++i) 48 cout<<1+i<<" "<<1+i+1<<" "<<0<<endl; 49 cout<<1<<" "<<2+a+1<<" "<<1<<endl; 50 for(int i=1;i<=b;++i) 51 cout<<2+a+i<<" "<<2+a+i+1<<" "<<0<<endl; 52 cout<<1<<" "<<3+a+b+1<<" "<<1<<endl; 53 for(int i=1;i<=c;++i) 54 cout<<3+a+b+i<<" "<<3+a+b+i+1<<" "<<0<<endl; 55 return 0; 56 } 57 } 58 return 0; 59 }