BZOJ2763 [JLOI2011] 飞行路线
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2763
Description
Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?
Input
数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。
第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t<n)
接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0<=a,b<n,a与b不相等,0<=c<=1000)
Output
只有一行,包含一个整数,为最少花费。
距离增加一维,d[i][j]表示第i个点距起点,免费j次的最短距离
Dijkstra 224ms,SPFA6500ms……差点卡进Status第一页,据说SPFA用SLF会更快
第一次使用指针保存邻接表
另外Status第二页怎么都是一堆熟悉的人啊……还有一堆高一好可怕……耀良,泽川,PoPoQQQ神犇(Orz),SA(Orz),KPM(Orz)
Dijkstra,224ms
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <queue> 6 #define rep(i,l,r) for(int i=l; i<=r; i++) 7 #define clr(x,y) memset(x,y,sizeof(x)) 8 #define travel(x) for(Edge *i=last[x]; i; i=i->pre) 9 using namespace std; 10 const int INF = 0x3f3f3f3f; 11 const int maxn = 10010; 12 struct Edge{ 13 Edge *pre; int to,cost; 14 }edge[100010]; 15 int n,m,k,s,t,x,y,z,ans,d[maxn][11]; 16 Edge *pt,*last[maxn]; 17 struct node{ 18 int x,k,d; 19 node(){} 20 node(int _x,int _k,int _d) : x(_x), k(_k), d(_d){}; 21 inline bool operator < (const node &_Tp) const{ 22 return d > _Tp.d; 23 } 24 }now; 25 priority_queue <node> q; 26 inline int read(){ 27 int ans = 0, f = 1; 28 char c = getchar(); 29 while (!isdigit(c)){ 30 if (c == '-') f = -1; 31 c = getchar(); 32 } 33 while (isdigit(c)){ 34 ans = ans * 10 + c - '0'; 35 c = getchar(); 36 } 37 return ans * f; 38 } 39 inline void addedge(int x,int y,int z){ 40 pt->pre = last[x]; 41 pt->to = y; 42 pt->cost = z; 43 last[x] = pt++; 44 } 45 void dijkstra(){ 46 clr(d,INF); clr(d[s],0); 47 q.push(node(s,0,0)); 48 rep(i,1,k) q.push(node(s,i,0)); 49 while (!q.empty()){ 50 now = q.top(); q.pop(); 51 if (now.d != d[now.x][now.k]) continue; 52 travel(now.x){ 53 if (d[now.x][now.k] + i->cost < d[i->to][now.k]){ 54 d[i->to][now.k] = d[now.x][now.k] + i->cost; 55 q.push(node(i->to,now.k,d[i->to][now.k])); 56 } 57 if (d[now.x][now.k] < d[i->to][now.k+1] && now.k < k){ 58 d[i->to][now.k+1] = d[now.x][now.k]; 59 q.push(node(i->to,now.k+1,d[i->to][now.k+1])); 60 } 61 } 62 } 63 } 64 int main(){ 65 n = read(); m = read(); k = read(); s = read(); t = read(); 66 clr(last,0); pt = edge; 67 rep(i,1,m){ 68 x = read(); y = read(); z = read(); 69 addedge(x,y,z); addedge(y,x,z); 70 } 71 dijkstra(); 72 ans = d[t][0]; 73 rep(i,1,k) ans = min(ans,d[t][i]); 74 printf("%d\n",ans); 75 return 0; 76 }
SPFA,6500ms
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <queue> 6 #define rep(i,l,r) for(int i=l; i<=r; i++) 7 #define clr(x,y) memset(x,y,sizeof(x)) 8 #define travel(x) for(Edge *i=last[x]; i; i=i->pre) 9 using namespace std; 10 const int INF = 0x3f3f3f3f; 11 const int maxn = 10010; 12 struct Edge{ 13 Edge *pre; int to,cost; 14 }edge[100010]; 15 int n,m,k,s,t,x,y,z,ans,d[maxn][11]; 16 bool isin[maxn][11]; 17 Edge *pt,*last[maxn]; 18 struct node{ 19 int x,k; 20 node(){} 21 node(int _x,int _k) : x(_x), k(_k){}; 22 }now; 23 queue <node> q; 24 inline int read(){ 25 int ans = 0, f = 1; 26 char c = getchar(); 27 while (!isdigit(c)){ 28 if (c == '-') f = -1; 29 c = getchar(); 30 } 31 while (isdigit(c)){ 32 ans = ans * 10 + c - '0'; 33 c = getchar(); 34 } 35 return ans * f; 36 } 37 inline void addedge(int x,int y,int z){ 38 pt->pre = last[x]; 39 pt->to = y; 40 pt->cost = z; 41 last[x] = pt++; 42 } 43 void spfa(){ 44 clr(d,INF); clr(d[s],0); clr(isin,0); 45 q.push(node(s,0)); isin[s][0] = 1; 46 rep(i,1,k) q.push(node(s,i)), isin[s][i] = 1; 47 while (!q.empty()){ 48 now = q.front(); q.pop(); isin[now.x][now.k] = 0; 49 travel(now.x){ 50 if (d[now.x][now.k] + i->cost < d[i->to][now.k]){ 51 d[i->to][now.k] = d[now.x][now.k] + i->cost; 52 if (!isin[i->to][now.k]){ 53 isin[i->to][now.k] = 1; 54 q.push(node(i->to,now.k)); 55 } 56 } 57 if (d[now.x][now.k] < d[i->to][now.k+1] && now.k < k){ 58 d[i->to][now.k+1] = d[now.x][now.k]; 59 if (!isin[i->to][now.k+1]){ 60 isin[i->to][now.k+1] = 1; 61 q.push(node(i->to,now.k+1)); 62 } 63 } 64 } 65 } 66 } 67 int main(){ 68 n = read(); m = read(); k = read(); s = read(); t = read(); 69 clr(last,0); pt = edge; 70 rep(i,1,m){ 71 x = read(); y = read(); z = read(); 72 addedge(x,y,z); addedge(y,x,z); 73 } 74 spfa(); 75 ans = d[t][0]; 76 rep(i,1,k) ans = min(ans,d[t][i]); 77 printf("%d\n",ans); 78 return 0; 79 }