zoukankan      html  css  js  c++  java
  • hdu 3790 最短路径问题

    Problem Description
    给你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
    输出 一行有两个数, 最短距离及其花费。
     
    分析:每条路径增加 了一个权值,但还是一道最短路的问题,只需要在更新距离的时候判断一下相等的情况
    Dijkstra版
    #include<iostream>
    #include<algorithm>
    #include<string>
    using namespace std;
    const int N = 1001;
    int g[N][N],w[N][N],n,m;
    int dist[N],cost[N];
    bool vis[N];
    void init()
    {
    for(int i=0;i<=n;i++)
    for(int j=0;j<=n;j++)
    {
    g[i][j]=INT_MAX;
    w[i][j]=INT_MAX;
    }
    }
    void Dijkstra(int s)
    {
    for(int i=1;i<=n;i++)
    {
    dist[i]=g[s][i];
    cost[i]=w[s][i];
    }
    dist[s]=0;
    cost[s]=0;
    memset(vis,false,sizeof(vis));
    vis[s]=true;
    for(int i=1;i<n;i++)
    {
    int mind=INT_MAX,v;
    for(int j=1;j<=n;j++)
    {
    if(vis[j]) continue;
    if(dist[j]<mind)
    {
    mind=dist[j];
    v=j;
    }
    }
    vis[v]=true;
    for(int k=1;k<=n;k++)
    {
    if(!vis[k] && g[v][k]!=INT_MAX)
    {
    int newdist=dist[v]+g[v][k];
    if(newdist<dist[k])
    {
    dist[k]=newdist;
    cost[k]=cost[v]+w[v][k];
    }
    else if(newdist==dist[k] && cost[v]+w[v][k]<cost[k])
    {
    cost[k]=cost[v]+w[v][k];
    }
    }
    }
    }
    }
    int main()
    {
    int a,b,c,d,s,t;
    while(scanf("%d %d",&n,&m)==2 && (n||m))
    {
    init();
    for(int i=0;i<m;i++)
    {
    scanf("%d %d %d %d",&a,&b,&c,&d);
    if(c<g[a][b])
    {
    g[a][b]=g[b][a]=c;
    w[a][b]=w[b][a]=d;
    }
    }
    scanf("%d %d",&s,&t);
    Dijkstra(s);
    printf("%d %d\n",dist[t],cost[t]);
    }
    return 0;
    }
    SPFA版
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;

    const int N = 1001;
    int g[N][N],w[N][N],n,m;
    int dist[N],cost[N];
    bool vis[N];
    int Q[N*100];
    void init()
    {
    for(int i=0;i<=n;i++)
    for(int j=0;j<=n;j++)
    g[i][j]=w[i][j]=INT_MAX;
    }
    void SPFA(int s,int t)
    {
    for(int i=1;i<=n;i++)
    {
    dist[i]=INT_MAX;
    cost[i]=INT_MAX;
    }
    dist[s]=cost[s]=0;
    memset(vis,false,sizeof(vis));
    vis[s]=true;
    int pri=1,end=2;
    Q[1]=s;
    while(pri<end)
    {
    int v=Q[pri];
    for(int i=1;i<=n;i++)
    {
    if(g[v][i]==INT_MAX)
    continue;
    int newdis=dist[v]+g[v][i];
    if(newdis<dist[i])
    {
    dist[i]=newdis;
    cost[i]=cost[v]+w[v][i];
    if(!vis[i])
    {
    Q[end++]=i;
    vis[i]=true;
    }
    }
    else if(newdis==dist[i]&&cost[v]+w[v][i]<cost[i])
    cost[i]=cost[v]+w[v][i];
    }
    vis[v]=false;
    pri++;
    }
    }
    int main()
    {
    int a,b,c,d,s,t;
    while(scanf("%d %d",&n,&m)==2 && (n||m))
    {
    init();
    for(int i=0;i<m;i++)
    {
    scanf("%d %d %d %d",&a,&b,&c,&d);
    if(c<g[a][b])
    {
    g[a][b]=g[b][a]=c;
    w[a][b]=w[b][a]=d;
    }
    }
    scanf("%d %d",&s,&t);
    SPFA(s,t);
    printf("%d %d\n",dist[t],cost[t]);
    }
    return 0;
    }


  • 相关阅读:
    CSS之各种居中
    三步教会你装系统
    65条最常用正则表达式
    MongoDB介绍
    MongoDB基本命令用
    log4j配置
    使用spring + ActiveMQ 总结
    log4j配置文件
    如何入侵局域网电脑
    目标检测的图像特征提取
  • 原文地址:https://www.cnblogs.com/nanke/p/2409862.html
Copyright © 2011-2022 走看看