zoukankan      html  css  js  c++  java
  • hdu 3790 最短路问题 (spfa练手)

    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
    输出 一行有两个数, 最短距离及其花费。
     
    Sample Input
    3 2
    1 2 5 6
    2 3 4 5
    1 3 0 0
     
    Sample Output
    9 11
     
    #include <cstdio>
    #include <map>
    #include <iostream>
    #include<cstring>
    #include<bits/stdc++.h>
    #define ll long long int
    #define M 6
    using namespace std;
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1};
    int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1};
    const int inf=0x3f3f3f3f;
    const ll mod=1e9+7;
    struct node{ 
        int next;
        int to;
        int d,p;
    };
    node edge[200007];
    int head[1007];
    int cnt;
    void add(int u,int v,int d,int p){
        edge[++cnt].next=head[u];
        edge[cnt].to=v;
        edge[cnt].d=d;
        edge[cnt].p=p;
        head[u]=cnt;
    }
    int n,m;
    int s,e;
    bool vis[1007];
    int dis[1007],cost[1007];
    void spfa(int x){
        for(int i=1;i<=n;i++){
            dis[i]=inf;
            cost[i]=inf;
        }
        dis[x]=cost[x]=0;
        memset(vis,0,sizeof(vis));
        queue<int > q;
        q.push(x);
        vis[x]=1;
        while(!q.empty()){
            int u=q.front();
            q.pop();
            vis[u]=0;
            for(int i=head[u];i!=0;i=edge[i].next){
                int to=edge[i].to; int d=edge[i].d; int p=edge[i].p;
                if(dis[to]>dis[u]+d||((dis[to]==dis[u]+d)&&(cost[to]>cost[u]+p))){
                    cost[to]=cost[u]+p;
                    dis[to]=dis[u]+d;
                    if(!vis[to]){
                        q.push(to);
                        vis[to]=1;
                    }
                }
            }
        }
            
    }
    int main(){
        //ios::sync_with_stdio(false);
        while(scanf("%d%d",&n,&m)!=EOF){
            if(!n&&!m) break;
            memset(head,0,sizeof(head));
            cnt=0;
            for(int i=1;i<=m;i++){
                int a,b,d,p;
                scanf("%d%d%d%d",&a,&b,&d,&p);
                add(a,b,d,p);
                add(b,a,d,p);
            }
            scanf("%d%d",&s,&e);
            spfa(s);
            printf("%d %d
    ",dis[e],cost[e]);
        }
    }
  • 相关阅读:
    Xshell 使用纪要
    矩阵求逆
    Ubuntu 增加新用户
    matlab 常用图像处理
    Surface Evolver 基本操作、使用指南和珍贵资料
    latex 裁剪图片
    Inkscape 输入希腊字母
    Pyton——int内部功能介绍
    python——登陆接口设计(循环方法)
    Python之三层菜单
  • 原文地址:https://www.cnblogs.com/wmj6/p/10367660.html
Copyright © 2011-2022 走看看