HDU 3790 最短路径(spfa)

来源:互联网 发布:关于护肤的软件 编辑:程序博客网 时间:2024/06/05 16:41
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
Sample Output

9 11

先是最短路径然后是最短时间,用spfa或dijkstra求最短路径,在对路径松弛的时候加上对时间的比较,如果从a经过c到b比从a直接到b路径要短,就进行一次路径和时间的松弛,如果路径相同,还要判断时间是否更短,如果是就要对时间松弛。

#include <cstdio>#include <queue>#include <vector>#include <cstring>using namespace std;const int M = 1005;const int INF = 0x3f3f3f3f;struct Node{int num, cost, timm;};vector<Node> adj[M];int dis[M], tim[M];int n, m;bool bo[M];void spfa(int st){memset(bo, false, sizeof(bo));queue<int> q;int t;for(int i=1;i<=n;i++){dis[i] = INF;tim[i] = INF;}tim[st] = dis[st] = 0;q.push(st);while(!q.empty()){t = q.front();q.pop();bo[t] = false;vector<Node>::iterator it;for(it=adj[t].begin();it!=adj[t].end();it++){if(dis[it->num]>dis[t]+it->cost){dis[it->num] = dis[t] + it->cost;tim[it->num] = tim[t] + it->timm;if(!bo[it->num]){bo[it->num] = true;q.push(it->num);}}else if(dis[it->num]==dis[t]+it->cost){dis[it->num] = dis[t] + it->cost;if(tim[it->num]>tim[t]+it->timm){tim[it->num] = tim[t] + it->timm;}if(!bo[it->num]){bo[it->num] = true;q.push(it->num);}}}}}int main(){int a, b, d, p, s, t;Node tmp;while(scanf("%d%d", &n, &m) && n){for(int i=1;i<=n;i++)adj[i].clear();for(int i=1;i<=m;i++){scanf("%d%d%d%d", &a, &b, &d, &p);tmp.num = b;tmp.cost = d;tmp.timm = p;adj[a].push_back(tmp);tmp.num = a;adj[b].push_back(tmp);}scanf("%d%d", &s, &t);spfa(s);printf("%d %d\n", dis[t], tim[t]);}return 0;}


原创粉丝点击