zoukankan      html  css  js  c++  java
  • hdu 3790(SPFA)

    最短路径问题

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 20948    Accepted Submission(s): 6231


    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
     
    题解:我是用的SPFA,在路径相等的情况下比较一下花费就OK。(dis[v]>dis[u]+d||(dis[v]==dis[u]+d)&&(cost[v]>cost[u]+p))
    #include <stdio.h>
    #include <algorithm>
    #include <string.h>
    #include <math.h>
    #include <queue>
    using namespace std;
    const int N = 1005;
    const int M =100005;
    const int INF =99999999;
    struct Edge{
        int v,d,p,next;
    }edge[2*M];
    int head[N];
    int n,m;
    void addedge(int u,int v,int d,int p,int &k){
        edge[k].v =v,edge[k].d =d,edge[k].p=p,edge[k].next=head[u],head[u]=k++;
    }
    int dis[N],time[N],cost[N];
    bool vis[N];
    bool spfa(int s){
        queue<int >q;
        memset(vis,false,sizeof(vis));
        memset(time,0,sizeof(time));
        for(int i=1;i<=n;i++){
            dis[i] = (i==s)?0:INF;
            cost[i] = (i==s)?0:INF;
        }
        q.push(s);
        time[s]++;
        while(!q.empty()){
            int u = q.front();
            q.pop();
            vis[u]=false;
            for(int k = head[u];k!=-1;k=edge[k].next){
                int v = edge[k].v,d= edge[k].d,p = edge[k].p;
                if(dis[v]>dis[u]+d||(dis[v]==dis[u]+d)&&(cost[v]>cost[u]+p)){
                    dis[v]=dis[u]+d;
                    cost[v]=cost[u]+p;
                    if(!vis[v]){
                        vis[v] = true;
                        time[v]++;
                        q.push(v);
                    }
                    if(time[v]>n) return false;
                }
            }
        }
        return true;
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF,n+m){
            memset(head,-1,sizeof(head));
            int tot = 0,u,v,d,p;
            for(int i=0;i<m;i++){
                scanf("%d%d%d%d",&u,&v,&d,&p);
                addedge(u,v,d,p,tot);
                addedge(v,u,d,p,tot);
            }
            int s,t;
            scanf("%d%d",&s,&t);
            spfa(s);
            printf("%d %d
    ",dis[t],cost[t]);
        }
        return 0;
    }
     
  • 相关阅读:
    在宏块级冗余可调的多描述视频编码算法方面取得进展(转载)
    C++单例模式
    C++手动实现库函数
    C#操作java平台生成的公钥
    C++之位操作符
    Windows 8 应用栏
    Windows 8 本地数据存储
    Win8的页面缓存
    操作符sizeof
    three.js结合geoJson绘制中国地图
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5489582.html
Copyright © 2011-2022 走看看