第十一周 11.8-11.14
11.8
闲来无事补CF。
CF 592 C The Big Race
题目比较简单。点在于有一个大数比较可以用log弄掉。
算LCM要先除再乘。算log要先强转double。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 using namespace std; 6 typedef long long LL; 7 8 LL gcd(LL a,LL b) 9 { 10 return b?gcd(b,a%b):a; 11 } 12 13 int main(void) 14 { 15 LL t,w,b; 16 scanf("%I64d%I64d%I64d",&t,&w,&b); 17 LL x,GCD=gcd(w,b),LCM=b/GCD*w; 18 if(log(double(w))+log(double(b))>log(double(t))+log(double(GCD))) x=min(min(w-1,b-1),t); 19 else x=t/LCM*min(w,b)+min(t%LCM,min(w-1,b-1)); 20 GCD=gcd(x,t); 21 printf("%I64d/%I64d ",x/GCD,t/GCD); 22 return 0; 23 }
11.9
什么都没干。
11.10
CF 592 D Super M
在树上找包含标记节点的最小子树。dfs最远点对。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 # define maxn 150100 7 int cnt,headlist[maxn]; 8 int is[maxn],val[maxn]; 9 int d=0,A=maxn,B=maxn; 10 11 struct node 12 { 13 int to,pre; 14 } edge[2*maxn]; 15 16 void add(int from,int to) 17 { 18 cnt++; 19 edge[cnt].pre=headlist[from]; 20 edge[cnt].to=to; 21 headlist[from]=cnt; 22 } 23 24 void dfs1(int pos,int fa,int dep) 25 { 26 for(int i=headlist[pos];i;i=edge[i].pre) 27 { 28 int to=edge[i].to; 29 if(to==fa) continue; 30 dfs1(to,pos,dep+1); 31 if(is[to]||val[to]) val[pos]+=2; 32 val[pos]+=val[to]; 33 } 34 if(is[pos]||val[pos]) 35 { 36 if(dep>d) {d=dep; A=pos;} 37 else if(dep==d) A=min(A,pos); 38 } 39 return; 40 } 41 42 void dfs2(int pos,int fa,int dep) 43 { 44 if(dep>d) {d=dep; B=pos;} 45 else if(dep==d) B=min(B,pos); 46 for(int i=headlist[pos];i;i=edge[i].pre) 47 { 48 int to=edge[i].to; 49 if(to==fa||!is[to]&&!val[to]) continue; 50 dfs2(to,pos,dep+1); 51 } 52 return; 53 } 54 55 int main(void) 56 { 57 int m,n; 58 scanf("%d%d",&n,&m); 59 for(int i=1;i<n;i++) 60 { 61 int u,v; 62 scanf("%d%d",&u,&v); 63 add(u,v); add(v,u); 64 } 65 int s; 66 for(int i=1;i<=m;i++) 67 { 68 int x; scanf("%d",&x); 69 is[s=x]=1; 70 } 71 dfs1(s,0,0); 72 d=0; dfs2(A,0,0); 73 printf("%d %d ",min(A,B),val[s]-d); 74 return 0; 75 }