Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
二话不说,贴代码数据很大,那就离散化呗 终点一定是从某一个梯子或者滑梯的端点,或起点过去的。因此我们只需要知道到每一个端点的最小步数,就可以求出到重点的最小步数。 求两点之间最小步数有以下几种情况: 1. 两点由滑梯或梯子连接,则只需要0步 2. 两点可以通过跳跃到达,则求跳跃步数,注意跳跃的时候要避开滑梯或梯子的起点 3. 两点见有连续s个梯子或滑梯的起点。此时跳跃无法到达(因为没法避开这些点) 讨论上述情况,然后SPFA就可以了 #include <iostream> #include <algorithm> #include <fstream> #define INF 2000000000 #define MAXN 90 using namespace std; ifstream fin("1.txt"); struct DATA { int pos; bool isStart; }; int roads[50][2]; DATA points[90]; int w,s,p; bool inQueue[90]; int spfaQueue[90]; int dist[90]; int pre[90]; int cmp(DATA a, DATA b) { if (a.pos<b.pos) return 1; else return 0; } int find_dist(int p1, int p2) { if (p1 == p2) return -1; for (int i=0;i<p-1;i++) //之间有梯子或滑梯 if (roads[i][0]==points[p1].pos && roads[i][1]==points[p2].pos) return 0; if (p1>p2) //不能倒着跑 return -1; if (points[p1].isStart) //如果是某个梯子或滑梯的起点,那么只有终点不是-1 return -1; int st=points[p1].pos; //st用来更新跳跃过程中所在的位置 int sum=0; for (int i=p1+1;i<p2;i++) { int tmp=points[i].pos-st; if (tmp%s == 0 && points[i].isStart) //用s这个距离跳,如果一个点在s的倍数上,避开它 { int ed=points[i].pos-1; int rest=s-1; int ctpoint=i-1; while (rest>0 && points[ctpoint].pos==ed && points[ctpoint].isStart) //如果避不开(连续s个点都是梯子起点)那就返回-1 { ed--; ctpoint--; rest--; } if (rest == 0) return -1; sum+=(ed-st)/s; if ((ed-st)%s != 0) sum++; st=ed; } } sum+=(points[p2].pos-st)/s; if ((points[p2].pos-st)%s !=0) sum++; return sum; } int main() { fin>>w; while (w != 0) { fin>>s>>p; for (int i=0;i<p;i++) { fin>>roads[i][0]>>roads[i][1]; points[i<<1].pos=roads[i][0]; points[i<<1].isStart=true; points[(i<<1)|1].pos=roads[i][1]; points[i<<1|1].isStart=false; } points[p<<1].pos=0; points[p<<1].isStart=false; points[p<<1|1].pos=w; points[p<<1|1].isStart=false; p++; sort(points,points+p*2,cmp); int k=p*2-1; for (int i=0;i<=k;i++) { inQueue[i]=false; dist[i]=INF; } dist[0]=0; int head=0,tail=1; spfaQueue[0]=0; while (head != tail) { int current=spfaQueue[head]; for (int i=0;i<=k;i++) { int tmp=find_dist(current,i); if (tmp != -1) { if (dist[current]+tmp<dist[i]) { dist[i]=dist[current]+tmp; if (!inQueue[i]) { spfaQueue[tail]=i; pre[i]=current; inQueue[i]=true; tail=(tail+1)%MAXN; } } } } inQueue[current]=false; head=(head+1)%MAXN; } for (int i=0;i<=k;i++) if (points[i].pos == w) cout<<dist[i]<<endl; fin>>w; } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator