Codeforces Round #563 (Div. 2) F. Ehab and the Big Finale

https://codeforces.com/problemset/problem/1174/F

https://codeforces.com/blog/entry/67388

有助于理解树链剖分 和 树分治

题解写得挺好

重链

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cmath>
  4 #include <cstring>
  5 #include <string>
  6 #include <algorithm>
  7 #include <iostream>
  8 using namespace std;
  9 #define ll long long
 10 
 11 
 12 const double eps=1e-8;
 13 const ll inf=1e9;
 14 const ll mod=1e9+7;
 15 const int maxn=2e5+10;
 16 
 17 struct node
 18 {
 19     int d;
 20     node *to;
 21 }*e[maxn];
 22 
 23 char str[20];
 24 int siz[maxn],fa[maxn],link[maxn],cnt_link;
 25 
 26 void dfs(int d)
 27 {
 28     node *p=e[d];
 29     siz[d]=1;
 30     while (p)
 31     {
 32         if (fa[d]!=p->d)
 33         {
 34             fa[p->d]=d;
 35             dfs(p->d);
 36             siz[d]+=siz[p->d];
 37         }
 38         p=p->to;
 39     }
 40 }
 41 
 42 void findleaf(int d)
 43 {
 44     node *p;
 45     int num;
 46     cnt_link=0;
 47     link[0]=d;
 48     while (1)
 49     {
 50         p=e[d];
 51         num=0;
 52         while (p)
 53         {
 54             if (fa[d]!=p->d)
 55             {
 56                 if (siz[p->d]>siz[num])
 57                     num=p->d;
 58             }
 59             p=p->to;
 60         }
 61         if (!num)
 62             break;
 63         link[++cnt_link]=num;
 64         d=num;
 65     }
 66 }
 67 
 68 int main()
 69 {
 70     node *p;
 71     int n,x,y,i,root,dist,r,pos;
 72     scanf("%d",&n);
 73     for (i=1;i<n;i++)
 74     {
 75         scanf("%d%d",&x,&y);
 76         p=new node();
 77         p->d=y;
 78         p->to=e[x];
 79         e[x]=p;
 80 
 81         p=new node();
 82         p->d=x;
 83         p->to=e[y];
 84         e[y]=p;
 85     }
 86     gets(str);
 87 
 88     printf("d %d\n",1);
 89     fflush(stdout);
 90     scanf("%d",&dist);
 91     if (dist==0)
 92     {
 93         printf("! %d\n",1);
 94         fflush(stdout);
 95         return 0;
 96     }
 97 
 98     root=1;
 99     while (1)
100     {
101         dfs(root);
102         findleaf(root);
103 
104         printf("d %d\n",link[cnt_link]);
105         fflush(stdout);
106         scanf("%d",&r);
107 
108         pos=(dist+cnt_link-r)/2;
109         root=link[pos];
110         dist=dist-pos;
111         if (dist==0)
112         {
113             printf("! %d\n",root);
114             fflush(stdout);
115             return 0;
116         }
117 
118         printf("s %d\n",root);
119         fflush(stdout);
120         scanf("%d",&root);
121         dist--;
122         if (dist==0)
123         {
124             printf("! %d\n",root);
125             fflush(stdout);
126             return 0;
127         }
128     }
129     return 0;
130 }
131 /*
132 6
133 1 2
134 2 3
135 3 4
136 4 5
137 5 6
138 
139 7
140 1 2
141 1 3
142 2 4
143 2 5
144 3 6
145 3 7
146 
147 
148 
149 7
150 1 2
151 1 3
152 2 4
153 2 5
154 3 6
155 3 7
156 d 1
157 2
158 d 7
159 4
160 s 1
161 2
162 d 7
163 */

树重心

为了省去vis初始化

way1:

use father vex

way2:

vis[d]=1;

...

vis[d]=0;

  1     #include <cstdio>
  2     #include <cstdlib>
  3     #include <cmath>
  4     #include <cstring>
  5     #include <string>
  6     #include <algorithm>
  7     #include <iostream>
  8     using namespace std;
  9     #define ll long long
 10      
 11      
 12     const double eps=1e-8;
 13     const ll inf=1e9;
 14     const ll mod=1e9+7;
 15     const int maxn=2e5+10;
 16      
 17     struct node
 18     {
 19         int d;
 20         node *to;
 21     }*e[maxn];
 22      
 23     char str[20];
 24     int siz[maxn],fa[maxn],link[maxn],cnt_link;
 25      
 26     void dfs(int d)
 27     {
 28         node *p=e[d];
 29         siz[d]=1;
 30         while (p)
 31         {
 32             if (fa[d]!=p->d)
 33             {
 34                 fa[p->d]=d;
 35                 dfs(p->d);
 36                 siz[d]+=siz[p->d];
 37             }
 38             p=p->to;
 39         }
 40     }
 41      
 42     void findleaf(int d)
 43     {
 44         node *p;
 45         int num;
 46         cnt_link=0;
 47         link[0]=d;
 48         while (1)
 49         {
 50             p=e[d];
 51             num=0;
 52             while (p)
 53             {
 54                 if (fa[d]!=p->d)
 55                 {
 56                     if (siz[p->d]>siz[num])
 57                         num=p->d;
 58                 }
 59                 p=p->to;
 60             }
 61             if (!num)
 62                 break;
 63             link[++cnt_link]=num;
 64             d=num;
 65         }
 66     }
 67      
 68     int main()
 69     {
 70         node *p;
 71         int n,x,y,i,root,dist,r,pos;
 72         scanf("%d",&n);
 73         for (i=1;i<n;i++)
 74         {
 75             scanf("%d%d",&x,&y);
 76             p=new node();
 77             p->d=y;
 78             p->to=e[x];
 79             e[x]=p;
 80      
 81             p=new node();
 82             p->d=x;
 83             p->to=e[y];
 84             e[y]=p;
 85         }
 86         gets(str);
 87      
 88         printf("d %d\n",1);
 89         fflush(stdout);
 90         scanf("%d",&dist);
 91         if (dist==0)
 92         {
 93             printf("! %d\n",1);
 94             fflush(stdout);
 95             return 0;
 96         }
 97      
 98         root=1;
 99         while (1)
100         {
101             fa[root]=0;
102             dfs(root);
103             findleaf(root);
104      
105             printf("d %d\n",link[cnt_link]);
106             fflush(stdout);
107             scanf("%d",&r);
108             if (r==0)
109             {
110                 printf("! %d\n",link[cnt_link]);
111                 fflush(stdout);
112                 return 0;
113             }
114      
115             pos=(dist+cnt_link-r)/2;
116             root=link[pos];
117             dist=dist-pos;
118             if (dist==0)
119             {
120                 printf("! %d\n",root);
121                 fflush(stdout);
122                 return 0;
123             }
124      
125             printf("s %d\n",root);
126             fflush(stdout);
127             scanf("%d",&root);
128             dist--;
129             if (dist==0)
130             {
131                 printf("! %d\n",root);
132                 fflush(stdout);
133                 return 0;
134             }
135         }
136         return 0;
137     }
138     /*
139     6
140     1 2
141     2 3
142     3 4
143     4 5
144     5 6
145      
146     */
  1     #include <cstdio>
  2     #include <cstdlib>
  3     #include <cmath>
  4     #include <cstring>
  5     #include <string>
  6     #include <algorithm>
  7     #include <iostream>
  8     using namespace std;
  9     #define ll long long
 10      
 11      
 12     const double eps=1e-8;
 13     const ll inf=1e9;
 14     const ll mod=1e9+7;
 15     const int maxn=2e5+10;
 16      
 17     struct node
 18     {
 19         int d;
 20         node *to;
 21     }*e[maxn];
 22      
 23     char str[20];
 24     int siz[maxn],fa[maxn],link[maxn],cnt_link;
 25     bool vis[maxn];
 26      
 27     void dfs(int d)
 28     {
 29         node *p=e[d];
 30         vis[d]=1;
 31         siz[d]=1;
 32         while (p)
 33         {
 34             if (!vis[p->d])
 35             {
 36                 dfs(p->d);
 37                 siz[d]+=siz[p->d];
 38                 fa[p->d]=d;
 39             }
 40             p=p->to;
 41         }
 42         vis[d]=0;
 43     }
 44      
 45     void findleaf(int d)
 46     {
 47         node *p;
 48         int num;
 49         cnt_link=0;
 50         link[0]=d;
 51         while (1)
 52         {
 53             p=e[d];
 54             num=0;
 55             while (p)
 56             {
 57                 if (fa[d]!=p->d)
 58                 {
 59                     if (siz[p->d]>siz[num])
 60                         num=p->d;
 61                 }
 62                 p=p->to;
 63             }
 64             if (!num)
 65                 break;
 66             link[++cnt_link]=num;
 67             d=num;
 68         }
 69     }
 70      
 71     int main()
 72     {
 73         node *p;
 74         int n,x,y,i,root,dist,r,pos;
 75         scanf("%d",&n);
 76         for (i=1;i<n;i++)
 77         {
 78             scanf("%d%d",&x,&y);
 79             p=new node();
 80             p->d=y;
 81             p->to=e[x];
 82             e[x]=p;
 83      
 84             p=new node();
 85             p->d=x;
 86             p->to=e[y];
 87             e[y]=p;
 88         }
 89         gets(str);
 90      
 91         printf("d %d\n",1);
 92         fflush(stdout);
 93         scanf("%d",&dist);
 94         if (dist==0)
 95         {
 96             printf("! %d\n",1);
 97             fflush(stdout);
 98             return 0;
 99         }
100      
101         root=1;
102         while (1)
103         {
104     //        memset(vis,0,sizeof(vis));
105             fa[root]=0;
106             dfs(root);
107             findleaf(root);
108      
109             printf("d %d\n",link[cnt_link]);
110             fflush(stdout);
111             scanf("%d",&r);
112             if (r==0)
113             {
114                 printf("! %d\n",link[cnt_link]);
115                 fflush(stdout);
116                 return 0;
117             }
118      
119             pos=(dist+cnt_link-r)/2;
120             root=link[pos];
121             dist=dist-pos;
122             if (dist==0)
123             {
124                 printf("! %d\n",root);
125                 fflush(stdout);
126                 return 0;
127             }
128      
129             printf("s %d\n",root);
130             fflush(stdout);
131             scanf("%d",&root);
132             dist--;
133             if (dist==0)
134             {
135                 printf("! %d\n",root);
136                 fflush(stdout);
137                 return 0;
138             }
139         }
140         return 0;
141     }
142     /*
143     6
144     1 2
145     2 3
146     3 4
147     4 5
148     5 6
149      
150     */

猜你喜欢

转载自www.cnblogs.com/cmyg/p/11108970.html
今日推荐