题解 P4667 【[BalticOI 2011 Day1]Switch the Lamp On】

_虹_

2018-10-24 20:35:35

Solution

其实并不一定要手写堆。 感谢伟大的STL造福众生。 介绍一些stl提供的~~我第一次用的~~堆操作函数。 - (以下所有end都是数组尾的下一个元素) - 生成堆:make_heap(T* begin,T* end),将一个无序数组组织成堆。 - 插入值:在数组尾加上插入的数值,再调用push_heap(T* begin,T* end);维护堆的性质。 - 弹出堆顶:pop_heap(T* begin,T* end);江堆顶移动到队列尾部,其他部分维持堆的性质。 - 插入弹出要求数组已经是一个堆 没了优先队列底层的vector,不吸氧,堆+dij也就ac了。 ~~跑了2758ms,最大点128ms。~~ ```cpp #include <iostream> #include <algorithm> //#include <memory.h> using namespace std; const unsigned int INT_MAX=2147483647; const int kmaxn=260000; const int kmaxm=kmaxn<<3; ///////////////////////////////////////////////////// struct unit { int first; int second; unit():first(0),second(0){}; unit(int f,int s):first(f),second(s){}; const int operator<(const unit& u)const { return first>u.first; } }; class p_queue { unit heap[kmaxm]; int otail; public: p_queue():otail(0){}; unit top(){ pop_heap(&heap[0],&heap[otail]); return heap[otail-1]; } void pop(){otail--;//以前是优先队列写的dij,干脆就这样凑活一下,其实top里弹出要安全一些,毕竟pop_heap之后数组尾元素已经不符合堆的性质了。 } void push(const unit v){ heap[otail++]=v; push_heap(&heap[0],&heap[otail]); } const bool empty()const{return !otail;} }q; ////////////////////////////////////////////////////// struct edge { int dest=0; long long int length=0; edge* next=NULL; }; const int max_pool_size=kmaxn<<2; edge memory_pool[max_pool_size]; int pool_otail; edge* list[kmaxn];//链式前向星是不会写的,这辈子也不会写前向星的 int result[kmaxn]; bool hsh[kmaxn]; void relax(int p) { edge* t=list[p]; while(t) { if(result[t->dest]>result[p]+t->length) { result[t->dest]=result[p]+t->length; q.push(unit(result[t->dest],t->dest)); } t=t->next; } } void shortest_path(const int start) { for(register int i=0;i<kmaxn;++i) result[i]=INT_MAX; q.push(unit(0,start)); result[start]=0; int count=0; int t=0; while(!q.empty()) { t=q.top().second; q.pop(); if(!hsh[t]) { relax(t); hsh[t]=true; } } } void add_edge(const int& s,const int &d,const long long int &w) { if(list[s]) { memory_pool[pool_otail].next=list[s]; } list[s]=&memory_pool[pool_otail++]; list[s]->dest=d; list[s]->length=w; } //////////////////////////////////////////////////// int n,m; char ch; int main() { ios::sync_with_stdio(false); cin>>n>>m; ++n; ++m; for(register int i=1;i<n;++i) { for(register int f=1;f<m;++f) { cin>>ch; if(ch=='\\') { //map[i][m*i+f]=1; add_edge(m*(i-1)+f,m*i+f+1,0); add_edge(m*i+f+1,m*(i-1)+f,0); add_edge(m*(i-1)+f+1,m*i+f,1); add_edge(m*i+f,m*(i-1)+f+1,1); } else { add_edge(m*(i-1)+f,m*i+f+1,1); add_edge(m*i+f+1,m*(i-1)+f,1); add_edge(m*(i-1)+f+1,m*i+f,0); add_edge(m*i+f,m*(i-1)+f+1,0); } } } shortest_path(1); if(result[n*m]==INT_MAX) { cout<<"NO SOLUTION"<<endl; } else { cout<<result[n*m]<<endl; } return 0; } ``` 本人蒟蒻,希望各位神犇指出错误QAQ。~~还希望管理员给个通过。~~