HDU 1535 Invitation Cards(SPFA,及其优化)
2014-07-24 10:06
190 查看
题意:
有编号1~P的站点, 有Q条公交车路线,公交车路线只从一个起点站直接到达终点站,是单向的,每条路线有它自己的车费。
有P个人早上从1出发,他们要到达每一个公交站点, 然后到了晚上再返回点1。 求所有人来回的最小费用之和。
思路:
1.两次SPFA,也就是巧妙的将路线进行了翻转。
code 1:(数据较大,不能用二维数组,用的邻接表)
这里SPFA 可以优化,关于SPFA的优化:
SLF:Small Label First 策略。
实现方法是,设队首元素为 i,队列中要加入节点 j,在 dj<=di 时加到队首而不是队尾,否则和普通的 SPFA 一样加到队尾。
LLL:Large Label Last 策略。
实现方法是,设队列 Q 中的队首元素为 i,距离标号的平均值为 avg(d),每次出队时,若 di>avg(d),把 i 移到队列末尾,如此反复,直到找到一个 i 使 ,di<=avg(d)将其出队。
有编号1~P的站点, 有Q条公交车路线,公交车路线只从一个起点站直接到达终点站,是单向的,每条路线有它自己的车费。
有P个人早上从1出发,他们要到达每一个公交站点, 然后到了晚上再返回点1。 求所有人来回的最小费用之和。
思路:
1.两次SPFA,也就是巧妙的将路线进行了翻转。
code 1:(数据较大,不能用二维数组,用的邻接表)
#include <stdio.h> #include <string.h> #include <algorithm> #include <queue> using namespace std; #define MAXN 1000000 #define INF 0x3f3f3f3f struct node { int now,to,w; }edge[MAXN];//记录每条边的信息,起始点,终止点,权值 int first[MAXN],next[MAXN]; int dis[MAXN],vis[MAXN]; int n,m; void turnup()//反转图 { int i,k; for(i = 0; i<=m; i++) first[i] = next[i] = -1; for(i = 0; i<m; i++) { k= edge[i].to; next[i] = first[k]; first[k] = i; } } void SPFA2(int start) { int i; for(i = 0; i<=n; i++) dis[i] = INF; dis[start] = 0; memset(vis,0,sizeof(vis)); queue<int> Q; Q.push(start); while(!Q.empty()) { start = Q.front(); Q.pop(); vis[start] = 0; i = first[start]; while(1) { int to = edge[i].now; if(dis[to]>dis[start]+edge[i].w) { dis[to]=dis[start]+edge[i].w; if(!vis[to]) { vis[to] = 1; Q.push(to); } } i = next[i]; if(i==-1) break; } } return; } void SPFA1(int start) { int i; for(i = 0; i<=n; i++) dis[i] = INF; dis[start] = 0; memset(vis,0,sizeof(vis)); queue<int> Q; Q.push(start); while(!Q.empty()) { start = Q.front(); Q.pop(); vis[start] = 0; i=first[start]; while(1) { int to = edge[i].to; if(dis[to]>dis[start]+edge[i].w) { dis[to]=dis[start]+edge[i].w; if(!vis[to]) { vis[to] = 1; Q.push(to); } } i = next[i]; if(i==-1) break; } } return; } int main() { int t,sum,i; scanf("%d",&t); while(t--) { sum = 0; scanf("%d%d",&n,&m); for(i=0; i<m; i++) first[i]=next[i]=-1; for(i=0; i<m; i++) { scanf("%d%d%d",&edge[i].now,&edge[i].to,&edge[i].w); next[i]=first[edge[i].now]; first[edge[i].now]=i; } SPFA1(1); for(i = 2; i<=n; i++) sum+=dis[i]; turnup(); SPFA2(1); for(i = 2; i<=n; i++) sum+=dis[i]; printf("%d\n",sum); } return 0; }
这里SPFA 可以优化,关于SPFA的优化:
SLF:Small Label First 策略。
实现方法是,设队首元素为 i,队列中要加入节点 j,在 dj<=di 时加到队首而不是队尾,否则和普通的 SPFA 一样加到队尾。
LLL:Large Label Last 策略。
实现方法是,设队列 Q 中的队首元素为 i,距离标号的平均值为 avg(d),每次出队时,若 di>avg(d),把 i 移到队列末尾,如此反复,直到找到一个 i 使 ,di<=avg(d)将其出队。
相关文章推荐
- HDU 1535 SPFA 前向星存图优化
- HDU 1535 Invitation Cards (最短路,附SLF优化SPFA)
- hdu1535 spfa
- HDU 1535 Invitation Cards(有向图单源最短路径+SPFA)
- HDU 1535 && POJ 1511 Invitation Cards (SPFA 模板 + 反向建图)
- Bellman-Ford 算法及其优化以及SPFA
- HDU 1535 Invitation Cards【SPFA最短路】【正反向建边求单源最短路之和】
- hdu 4198 写spfa不能忘了优化
- hdu 1535 || poj 1511 Invitation Cards(heap + dijstra || spfa)
- HDU 1535 Invitation Cards (spfa, 链式前向星,逆向建图)
- HDU 1535 Invitation Cards 有向图的来回最短路(邻接表反向建图)+spfa
- hdu 2544 【总结】 Dijkstra,Bellman-Ford ,SPFA 最短路求法及对应优化
- Bellman-Ford算法及其队列优化(SPFA)
- HDU 1535 Invitation Cards 【SPFA + 链式前向星】
- hdu 1535 Invitation Cards(spfa)
- hdu 1317+hdu 1535(SPFA)
- Bellman-Ford算法及其队列优化(SPFA)
- hdu 1535 spfa
- (spfa专题 1.1)hdu 1535 Invitation Cards(求从1到2~n的点后,再从2~n返回1点的最小距离)
- hdu 1535 Invitation Cards(邻接表spfa)