1. 程式人生 > 其它 >[cf1340D]Nastya and Time Machine

[cf1340D]Nastya and Time Machine

記$deg_{i}$為$i$的度數,簡單分類討論可得答案下限為$\max_{i=1}^{n}deg_{i}$

另一方面,此下限是可以取到的,構造方法較多,這裡給一個巧妙一些的做法——

對其以dfs(兒子順序任意),並要求如果一個節點被父親遞迴時時間為$t+1$,則返回時時間為$t$,那麼父親的時間即恰從$t$變為$t+1$

下面考慮如何保證此性質,每一個節點有兩種情況:

1.其過程中某次要遞迴兒子時,其時間達到了$\max_{i=1}^{n}deg_{i}$(那麼搜下去即超過了此下限),那麼將其的時間改為$t-son$(其中$t+1$為其被父親遞迴時時間,$son$為剩餘兒子數,顯然$t\ge son$)

2.某點不存在上述情況,則在最後將其的時間改為$t$(意義與上面相同)

由此,即可歸納上述性質

時間複雜度為$o(n)$,可以通過

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 100005
 4 vector<int>v[N];
 5 vector<pair<int,int> >ans;
 6 int n,T,x,y,lim;
 7 void dfs(int k,int fa){
 8     int t=T-1;
 9     for(int i=0;i<v[k].size();i++)
10 if (v[k][i]!=fa){ 11 if (T==lim){ 12 T=t; 13 for(int j=i;j<v[k].size();j++) 14 if (v[k][j]!=fa)T--; 15 ans.push_back(make_pair(k,T)); 16 } 17 ans.push_back(make_pair(v[k][i],++T)); 18
dfs(v[k][i],k); 19 ans.push_back(make_pair(k,++T)); 20 } 21 if ((k!=1)&&(t!=T)){ 22 ans.push_back(make_pair(k,t)); 23 T=t; 24 } 25 } 26 int main(){ 27 scanf("%d",&n); 28 for(int i=1;i<n;i++){ 29 scanf("%d%d",&x,&y); 30 v[x].push_back(y); 31 v[y].push_back(x); 32 } 33 for(int i=1;i<=n;i++)lim=max(lim,(int)v[i].size()); 34 ans.push_back(make_pair(1,0)); 35 dfs(1,0); 36 printf("%d\n",(int)ans.size()); 37 for(int i=0;i<ans.size();i++)printf("%d %d\n",ans[i].first,ans[i].second); 38 return 0; 39 }
View Code