UOJ #216 最小花费最短路

Posted ukcxrtjr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UOJ #216 最小花费最短路相关的知识,希望对你有一定的参考价值。

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

【输入描述】: 多组数据:每组数据描述如下:

输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。

n和m为0时输入结束。

【输出描述】: 输出一行有两个数, 最短距离及其花费。

【样例输入】: 3 2 1 2 5 6 2 3 4 5 1 3 0 0 【样例输出】: 9 11 【时间限制、数据范围及描述】: 时间:1s 空间:128M

对于 30%的数据:1<n<=100

对于100%的数据:1<n<=1000; 0<m<100000; s != t; 1<=d,p<=1000

数据组数<=5,注意卡常;

本题就是在最短路模板中加一句判断,就是当(Cost[v]>Cost[u]+Edge[i].cost&&dis[v]==dis[u]+Edge[i].w) 时,即当前搜到的是最短路,但花费并不是最优,这时也将Cost[v]更新为Cost[u]+Edge[i].cost,即在搜索最短路的过程中同时更新花费最优值,这样就可以求解最小花费了。

Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<queue>
using namespace std;
const int N=1000005,M=5000005,INF=1000000005;
int n,m,s,t,Cnt,dis[N],vis[N],head[M],Cost[N];
struct Edge
    int u,v,w,cost,Next;
Edge[M];
void Push(int u,int v,int w,int cost)
    Edge[++Cnt].Next=head[u];
    Edge[Cnt].v=v;
    Edge[Cnt].w=w;
    Edge[Cnt].cost=cost;
    head[u]=Cnt;

void SPFA()
    queue<int> q;
    for(int i=1;i<=n;i++)
        dis[i]=INF;
        vis[i]=0;
    
    q.push(s);
    dis[s]=0;
    Cost[s]=0;
    vis[s]=1;
    while(!q.empty())
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];i;i=Edge[i].Next)
            int v=Edge[i].v; 
            if(dis[v]>dis[u]+Edge[i].w||(Cost[v]>Cost[u]+Edge[i].cost&&dis[v]==dis[u]+Edge[i].w))
                dis[v]=dis[u]+Edge[i].w;
                Cost[v]=Cost[u]+Edge[i].cost;
                if(vis[v]==0)
                    vis[v]=1;
                    q.push(v);
                
            
        
    

int main()
    int u,v,w,c;
    while(scanf("%d%d",&n,&m))
        memset(head,0,sizeof(head));
        memset(Cost,0x3f,sizeof(Cost));
        if(n==0||m==0)
            break;
        
        for(int i=1;i<=m;i++)
            scanf("%d%d%d%d",&u,&v,&w,&c);
            Push(u,v,w,c);
            Push(v,u,w,c);
        
        scanf("%d%d",&s,&t);
        SPFA();
        printf("%d %d\n",dis[t],Cost[t]);
    
    return 0;

以上是关于UOJ #216 最小花费最短路的主要内容,如果未能解决你的问题,请参考以下文章

HDU 3790最短路径问题 [最短路最小花费]

[最短路] aw1126. 最小花费(单源最短路建图+知识理解+代码细节+好题)

AOJ2249 最短路+最小花费(双权值)

HDU 1385 Minimum Transport Cost (输出字典序最小路径)最短路

hdu 6852Path6(最短路+最小割)

UOJ244[UER7]短路