BZOJ2599: [IOI2011]Race

裸的点分治

自从前两天狂敲了一个广搜点分治之后 敲个点分治如鱼得水啊

总觉得自己的写法会被奇怪数据卡到O(n2)

幸好IOI数据比较仁慈…

调试小结:

  1. now、po不分

  2. dis、deep不分

P.S. IOI的数据格式…不想讲了

  1 /**************************************************************
  2     Problem: 2599
  3     User: zhuohan123
  4     Language: C++
  5     Result: Accepted
  6     Time:30648 ms
  7     Memory:43504 kb
  8 ****************************************************************/
  9  
 10 #include <iostream>
 11 #include <cstdio>
 12 #include <algorithm>
 13 //#define ONLINE_JUDGE
 14 using namespace std;
 15 inline int imin(int a,int b){return a<b?a:b;}
 16 int n,k;
 17 struct point{int f,head,deep,dis,size,wt;bool havevis;}p[210000];
 18 struct edge{int next,to,c;}g[510000];int gnum;
 19 void addedge(int from,int to,int c)
 20 {
 21     g[++gnum].to=to;g[gnum].c=c;g[gnum].next=p[from].head;p[from].head=gnum;
 22 }
 23 int q1[1100000],l1=1,r1=0;
 24 int bfsx[110000],bfsnum;
 25 void BFS(int po)
 26 {
 27     p[po].f=0;p[po].deep=0;p[po].dis=0;
 28     l1=1;r1=0;bfsnum=0;
 29     q1[++r1]=po;
 30     while(l1<=r1)
 31     {
 32         int now=q1[l1++];
 33         bfsx[++bfsnum]=now;
 34         p[now].size=1;
 35         for(int i=p[now].head;i;i=g[i].next)
 36             if(g[i].to!=p[now].f&&!p[g[i].to].havevis)
 37             {
 38                 p[g[i].to].f=now;
 39                 p[g[i].to].deep=p[now].deep+1;
 40                 p[g[i].to].dis=p[now].dis+g[i].c;
 41                 q1[++r1]=g[i].to;
 42             }
 43     }
 44     for(int i=bfsnum;i>1;i--)p[p[bfsx[i]].f].size+=p[bfsx[i]].size;
 45 }
 46 int bestroot(int po)
 47 {
 48     int halfsize=p[po].size/2;
 49     while(true)
 50     {
 51         int bpo=0,bsize=-1;
 52         for(int i=p[po].head;i;i=g[i].next)
 53             if(!p[g[i].to].havevis&&bsize<p[g[i].to].size)bsize=p[bpo=g[i].to].size;
 54         if(bsize<=halfsize)return po;
 55         p[po].size-=p[bpo].size;
 56         p[bpo].size+=p[po].size;
 57         po=bpo;
 58     }
 59 }
 60 int q3[1100000],l3=1,r3=0;
 61 void settree(int po)
 62 {
 63     l3=1;r3=0;
 64     q3[++r3]=po;
 65     while(l3<=r3)
 66     {
 67         int now=q3[l3++];
 68         p[now].wt=po;
 69         for(int i=p[now].head;i;i=g[i].next)
 70             if(g[i].to!=p[now].f&&!p[g[i].to].havevis)
 71             q3[++r3]=g[i].to;
 72     }
 73 }
 74 struct isort
 75 {
 76     int wt,dis,deep;
 77     isort(){wt=dis=deep=0;}
 78     isort(int Wt,int Dis,int Deep){wt=Wt;dis=Dis;deep=Deep;}
 79     friend bool operator<(isort a,isort b)
 80     {
 81         if(a.dis<b.dis)return true;
 82         else if(a.dis==b.dis&&a.wt<a.wt)return true;
 83         else if(a.dis==b.dis&&a.wt==a.wt&&a.deep<b.deep)return true;
 84         return false;
 85     }
 86 }s[1100000];int snum;
 87 int q4[1100000],l4=1,r4=0;
 88 void BFS2(int po)
 89 {
 90     l4=1;r4=0;
 91     q4[++r4]=po;
 92     while(l4<=r4)
 93     {
 94         int now=q4[l4++];
 95         s[++snum]=isort(p[now].wt,p[now].dis,p[now].deep);
 96         for(int i=p[now].head;i;i=g[i].next)
 97             if(g[i].to!=p[now].f&&!p[g[i].to].havevis)
 98             q4[++r4]=g[i].to;
 99     }
100 }
101 int q2[1100000],l2=1,r2=0;
102 int ans=2147483647;
103 void idivide()
104 {
105     l2=1;r2=0;
106     q2[++r2]=1;
107     while(l2<=r2)
108     {
109         int now=q2[l2++];
110         BFS(now);
111         now=bestroot(now);
112         BFS(now);
113         p[now].havevis=true;
114         for(int i=p[now].head;i;i=g[i].next)
115             if(!p[g[i].to].havevis)settree(g[i].to);
116         /*cout<<"------------------------------------------"<<endl;
117         cout<<now<<endl;
118         for(int i=1;i<=n;i++)cout<<i<<" f="<<p[i].f<<" deep="<<p[i].deep<<" dis="
119         <<p[i].dis<<" size="<<p[i].size<<" wt="<<p[i].wt<<" havevis="<<p[i].havevis<<endl;
120         cout<<"------------------------------------------"<<endl;*/
121         snum=0;
122         BFS2(now);
123         sort(s+1,s+snum+1);
124         int r=snum;
125         for(int l=1;l<=snum;l++)
126         {
127             //if(s[l].dis==s[l-1].dis&&s[l].wt==s[l-1].wt)continue ;
128             if(s[l].dis==k)
129             {
130                 ans=imin(ans,s[l].deep);
131                 continue;
132             }
133             if(s[l].dis>k)break ;
134             while(r&&(s[l].dis+s[r].dis>k))r--;
135             if(r<=0)break ;
136             if(s[l].dis+s[r].dis<k)continue ;
137             for(int tempr=r;s[l].dis+s[tempr].dis==k;tempr--)
138                 if(s[tempr].wt!=s[l].wt)
139                     ans=imin(ans,s[l].deep+s[tempr].deep);
140         }
141         for(int i=p[now].head;i;i=g[i].next)
142             if(!p[g[i].to].havevis)q2[++r2]=g[i].to;
143     }
144 }
145 int main(int argc, char *argv[])
146 {
147     #ifndef ONLINE_JUDGE
148         freopen("1.in","r",stdin);
149         freopen("1.out","w",stdout);
150     #endif
151     scanf("%d%d",&n,&k);
152     for(int i=1;i<n;i++)
153     {
154         int from,to,c;scanf("%d%d%d",&from,&to,&c);
155         from++;to++;
156         addedge(from,to,c);addedge(to,from,c);
157     }
158     p[0].deep=-1;
159     idivide();
160     if(ans==2147483647)ans=-1;
161     //IOI丧心病狂数据
162     #ifdef CENA
163         int expect;scanf("%d",&expect);
164         if(expect==ans)printf("Correct.\n");
165         else printf("My:%d Std:%d",ans,expect);
166     #else
167         printf("%d\n",ans);
168     #endif
169     return 0;
170 }

 

 还有一句老话:

  简单数据结构 永远不要用 STL!!!

 

posted @ 2013-08-01 20:49  zhuohan123  阅读(530)  评论(0编辑  收藏  举报