首页 > 代码库 > ZOJ3088 Easter Holidays spfa 最长路 最短路 路径打印
ZOJ3088 Easter Holidays spfa 最长路 最短路 路径打印
题目链接:
3088
题意:一个滑雪胜地包含了n 个地点,m 个滑雪斜坡,k 架雪橇,其中2≤n≤1000、1≤m≤1000、1≤k≤1000。滑雪斜坡和雪橇总是从一个地点到另一个地点:滑雪斜坡是从高地点到低地点,而雪橇刚好相反(注意,雪橇不能下降)。Per 是一个滑雪初学者,他很害怕雪橇,尽管他想滑得尽可能快。现在,他发现他可以选择不同的雪橇和滑雪斜坡。他现在想这样安排他的滑雪行程:
2) 这个过程分为两个阶段:第一阶段,乘坐一架或多架雪橇上升;第二阶段,一直滑下来直到起点
3) 可能少地避免惊慌。这样,如果花在滑坡斜面上的时间与花在乘坐和等候雪橇的时间的比率越大就越好。
你能帮Per 找到一条惊慌最少的行程吗?
题解:
求两段路程的最大比率 即为求第一段的最长路径和第二段的最短路径(spfa算法) 且它们的起点和终点刚好相反 然后通过spfa(遍历所有起点 用dis数组记录到达所有其他点的最长路和最短路,并用path数组记录路径),最后枚举所有起点终点 输出比率的最大值即可。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define maxx 0x3f3f3f3f using namespace std; struct node{ int to,w,pre; } edge[2][1005]; //一维0表示滑坡 1表示雪橇 int dis[2][1005][1005]; //dis path的第二维表示所有起点 int path[2][1005][1005]; int next[2][1005]; int vis[2][1005]; int loc[1005]; //记录结果路径 int m,s1,s2; void addedge(int x){ int u,v,we,d; scanf("%d%d%d",&u,&v,&we); if(x==0)d=s1; else d=s2; edge[x][d].to=v; edge[x][d].w=we; edge[x][d].pre=next[x][u]; next[x][u]=d; if(x==0)s1++; else s2++; return; } void spfa(int x,int start){ queue<int>q; int head; dis[x][start][start]=0; q.push(start); while(!q.empty()){ head=q.front(); q.pop(); vis[x][head]=0; for(int i=next[x][head]; i!=-1; i=edge[x][i].pre){ int u=head,v=edge[x][i].to,we=edge[x][i].w; if(x==0){ if(dis[x][start][v]<dis[x][start][u]+we){ dis[x][start][v]=dis[x][start][u]+we; path[x][start][v]=u; if(!vis[x][v]){ vis[x][v]=1; q.push(v); } } } else{ if(dis[x][start][v]>dis[x][start][u]+we){ dis[x][start][v]=dis[x][start][u]+we; path[x][start][v]=u; if(!vis[x][v]){ vis[x][v]=1; q.push(v); } } } } } return; } int main(){ int t,n,k,i,j; scanf("%d",&t); while(t--){ s1=s2=0; scanf("%d%d%d",&m,&n,&k); for(i=1; i<=m; i++){ next[0][i]=next[1][i]=-1; for(j=i; j<=m; j++){ path[0][i][j]=path[1][i][j]=path[0][j][i]=path[1][j][i]=-1; dis[0][i][j]=dis[0][j][i]=0; dis[1][j][i]=dis[1][i][j]=maxx; } } while(n--){ addedge(0); } while(k--){ addedge(1); } for(i=1; i<=m; i++){ memset(vis,0,sizeof(vis)); spfa(0,i); spfa(1,i); } double ans=0,q1,q2,q3; int start,endd,s3=0,pos; for(i=1; i<=m; i++) for(j=1; j<=m; j++){ if(i==j||dis[0][i][j]==0||dis[1][j][i]==maxx) continue; q1=dis[0][i][j],q2=dis[1][j][i]; q3=q1/q2; if(q3>ans) {start=i,endd=j,ans=q3;} } pos=endd; while(path[0][start][pos]!=-1){ loc[s3++]=pos; pos=path[0][start][pos]; } while(path[1][endd][pos]!=-1){ loc[s3++]=pos; pos=path[1][endd][pos]; } cout<<endd; for(i=s3-1;i>=0;i--) cout<<' '<<loc[i]; printf("\n%.3lf\n",ans); } return 0; }
ZOJ3088 Easter Holidays spfa 最长路 最短路 路径打印
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。