CF 96D Volleyball(最短路套最短路)
2014-06-29 12:21
176 查看
题目链接:http://codeforces.com/contest/96/problem/D
题意:不超过1000个点和1000条边的无向图,n个点每个点有一辆出租车,给出每辆出租车能开的最远距离和搭乘这辆车的费用,求起点到终点的最少费用是多少。
解法:SPFA里套一个SPFA。第一个是利用乘坐某点的出租车A是否可以更新其他点的最少费用,但是从此点A出发还要求出此点到所有点的最短距离,所以要套一个SPFA,不过可以有个剪枝:如果求得的最短距离大于了从此点出发的出租车A能走得最远距离,那么就不用加入队列了。因为是个稀疏图,所以SPFA比dijkstra要快很多。
代码:
题意:不超过1000个点和1000条边的无向图,n个点每个点有一辆出租车,给出每辆出租车能开的最远距离和搭乘这辆车的费用,求起点到终点的最少费用是多少。
解法:SPFA里套一个SPFA。第一个是利用乘坐某点的出租车A是否可以更新其他点的最少费用,但是从此点A出发还要求出此点到所有点的最短距离,所以要套一个SPFA,不过可以有个剪枝:如果求得的最短距离大于了从此点出发的出租车A能走得最远距离,那么就不用加入队列了。因为是个稀疏图,所以SPFA比dijkstra要快很多。
代码:
/****************************************************** * @author:xiefubao *******************************************************/ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cmath> #include <map> #include <set> #include <stack> #include <string.h> //freopen ("in.txt" , "r" , stdin); using namespace std; #define eps 1e-8 #define zero(_) (abs(_)<=eps) const double pi=acos(-1.0); typedef long long LL; const int Max=1010; const LL INF=0x3FFFFFFFFFFFFFFF; int n,m; int S,e; int cango[Max]; int money[Max]; vector< pair<int,LL> > vec[Max]; LL dist[Max]; int tool[Max*Max]; int left1=0,right1=1; bool rem[Max]; LL mindist[Max]; int s[Max*Max]; void spfa() { for(int i=0; i<n; i++) dist[i]=INF; dist[S]=0; tool[0]=S; while(left1<right1) { int t=tool[left1]; for(int i=0;i<n;i++) mindist[i]=INF; s[0]=t; mindist[t]=0; int left=0,right=1; while(left<right) { int tt=s[left]; for(int i=0;i<vec[tt].size();i++) { int next=vec[tt][i].first; int di=mindist[tt]+vec[tt][i].second; if(mindist[next]>di&&di<=cango[t]) { mindist[next]=di; s[right++]=next; if(dist[next]>dist[t]+money[t]) { dist[next]=dist[t]+money[t]; tool[right1++]=next; } } } left++; } left1++; } } int main() { scanf("%d%d%d%d",&n,&m,&S,&e); S--,e--; for(int i=0; i<m; i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); a--,b--; vec[a].push_back(pair<int,LL>(b,(LL)(c))); vec[b].push_back(pair<int,LL>(a,(LL)(c))); } for(int i=0; i<n; i++) scanf("%d%d",cango+i,money+i); spfa(); if(dist[e]==INF) puts("-1"); else cout<<dist[e]<<'\n'; return 0; }
相关文章推荐
- E. Paths and Trees (CF 303 div2)最短路
- CF 241E flights 最短路,重复迭代直到稳定 难度:3
- Codeforces 96D Volleyball【重构图最短路】
- cf938d(建图技巧+最短路新模板)
- cf 2016愚人节专场 函数指针 最短路
- CF 586B 起点到终点的最短路和次短路之和
- CF95C volleyball [最短路+想法]
- CF-30 D - King's Problem?(枚举+最短路)
- CF 144D Missile Silos [最短路+想法]
- CF-30 D - King's Problem?(枚举+最短路)
- cf 689 B(最短路)
- [CF 242C][BNUOJ 26638] King's Path [最短路]
- 【打CF,学算法——三星级】CodeForces 689B Mike and Shortcuts (最短路+spfa)
- cf 507E Breaking Good 最短路
- CF Destroying Roads (最短路)
- CF 715B 最短路
- cf 602 C(最短路)
- CF 173B Chamber of Secrets 最短路
- CF 505B Mr. Kitayuta's Colorful Graph(最短路)
- cf 843 D Dynamic Shortest Path [最短路+bfs]