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!!!

 

你可能感兴趣的:(RAC)