bzoj2599 [IOI2011]Race
不知为什么我原来上传的题解不见了,整理的时候才发现QAQ???
树状数组维护权值为0~k的有多少,先查询一条路径再更新树状数组
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 cint inf=214748364; 27 void inin(int &ret) 28 { 29 ret=0;int f=0;char ch=getchar(); 30 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 31 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 32 ret=f?-ret:ret; 33 } 34 int n,k,ans; 35 int ji[1000010],w[200020],head[200020],next[400040],zhi[400040],si[200020],bo[200020],ed,v[400040]; 36 void add(int a,int b,int c) 37 { 38 next[++ed]=head[a],head[a]=ed,zhi[ed]=b,v[ed]=c; 39 next[++ed]=head[b],head[b]=ed,zhi[ed]=a,v[ed]=c; 40 } 41 int root,sum,shu[200020],dis[200020]; 42 void getroot(int x,int fa) 43 { 44 si[x]=1;w[x]=0; 45 for(int i=head[x];i;i=next[i]) 46 if(zhi[i]!=fa&&!bo[zhi[i]]) 47 { 48 getroot(zhi[i],x); 49 si[x]+=si[zhi[i]]; 50 w[x]=max(w[x],si[zhi[i]]); 51 } 52 w[x]=max(w[x],sum-si[x]); 53 if(w[x]<w[root])root=x; 54 } 55 void js(int x,int fa) 56 { 57 if(dis[x]>k)return; 58 ans=min(ans,shu[x]+((ji[k-dis[x]]||k==dis[x])?ji[k-dis[x]]:inf)); 59 for(int i=head[x];i;i=next[i]) 60 if(zhi[i]!=fa&&!bo[zhi[i]]) 61 { 62 shu[zhi[i]]=shu[x]+1; 63 dis[zhi[i]]=dis[x]+v[i]; 64 js(zhi[i],x); 65 } 66 } 67 void add(int x,int fa) 68 { 69 if(dis[x]>k)return; 70 ji[dis[x]]=min(shu[x],ji[dis[x]]?ji[dis[x]]:inf); 71 for(int i=head[x];i;i=next[i])if(!bo[zhi[i]]&&zhi[i]!=fa) 72 add(zhi[i],x); 73 } 74 void del(int x,int fa) 75 { 76 if(dis[x]>k)return; 77 ji[dis[x]]=0; 78 for(int i=head[x];i;i=next[i])if(!bo[zhi[i]]&&zhi[i]!=fa) 79 del(zhi[i],x); 80 } 81 void solve(int x) 82 { 83 bo[x]=1,ji[0]=0; 84 for(int i=head[x];i;i=next[i])if(!bo[zhi[i]]) 85 { 86 shu[zhi[i]]=1,dis[zhi[i]]=v[i]; 87 js(zhi[i],0); 88 add(zhi[i],0); 89 } 90 for(int i=head[x];i;i=next[i])if(!bo[zhi[i]])del(zhi[i],0); 91 for(int i=head[x];i;i=next[i])if(!bo[zhi[i]]) 92 { 93 root=0; 94 sum=si[zhi[i]]; 95 getroot(zhi[i],0); 96 solve(root); 97 } 98 } 99 int CSC() 100 { 101 freopen("in.in","r",stdin); 102 freopen("out.out","w",stdout); 103 inin(n),inin(k); 104 re(i,2,n) 105 { 106 int q,w,e; 107 inin(q),inin(w),inin(e); 108 q++,w++; 109 add(q,w,e); 110 } 111 w[0]=sum=ans=n; 112 getroot(1,0); 113 solve(root); 114 if(ans==n)cout<<-1; 115 else printf("%d",ans); 116 return 0; 117 }