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