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 }

 

posted @ 2016-03-10 11:21  HugeGun  阅读(168)  评论(0编辑  收藏  举报