HDU 3790 (最短距离 + 花费)

题意:

给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。

#include<bits/stdc++.h>
using namespace std;
const int maxN = 1e4 + 7;
const int maxM = 100000 + 7;
const int inf = 1e9 + 7;
int n, m, ecnt;
int head[maxN];
struct{
    int to, d, c, nxt;
}edge[2 * maxM];
void init(){
    memset(head, -1, sizeof(head));
    ecnt = 0;
}
void addEdge(int u, int v, int d, int c){
    edge[ecnt].to = v;
    edge[ecnt].d = d;
    edge[ecnt].c = c;
    edge[ecnt].nxt = head[u];
    head[u] = ecnt++;
}
int dist[maxN], cost[maxN], vis[maxN];
void spfa(int S, int E){
    fill(dist, dist + maxN , inf);
    fill(cost, cost + maxN, inf);
    memset(vis, 0, sizeof(vis));
    queue<int> q;
    q.push(S);
    dist[S] = 0;
    cost[S] = 0;
    vis[S] = 1;

    while(!q.empty()){
        int u = q.front();
        for(int i = head[u]; i != -1; i = edge[i].nxt){
            int v = edge[i].to, d = edge[i].d, c = edge[i].c;
            if(dist[u] + d < dist[v]){ //路径短的话直接更新
                dist[v] = dist[u] + d;
                cost[v] = cost[u] + c;
                q.push(v);
                if(!vis[v]){
                    vis[v] = 1;
                    q.push(v);
                }
            }else if(dist[u] + d == dist[v]){ //路径相等的话更新cost的最小值
                cost[v] = min(cost[v] , cost[u] + c);
            }
        }
        vis[u] = 0;
        q.pop();
    }
    cout << dist[E] << " " << cost[E] << "\n";
}
int main(){
//    freopen("1.txt","r", stdin);
    ios::sync_with_stdio(false);
    while(cin >> n >> m){
        if(n == 0) break;
        init();
        for(int i = 0; i < m; i++){
            int u, v, d, c;
            cin >> u >> v >> d >> c;
            addEdge(u,v,d,c);
            addEdge(v,u,d,c);
        }
        int S, E;
        cin >> S >> E;
        spfa(S, E);

    }
}

猜你喜欢

转载自www.cnblogs.com/Jadon97/p/9416256.html