[校内训练19_09_06]直径

题意

构造一棵树,让它有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 }
View Code

 

转载于:https://www.cnblogs.com/GreenDuck/p/11553765.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值