• hdu3790 最短路径问题(spfa)


    最短路径问题

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


    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,当两条路相等的时候选择花费最少的路即可。
     
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define INF 999999999
    using namespace std;
    struct Node{
        int s,t,c,q;
    }edge[200000];
    int N,M;
    int next1[200000],head[2000];
    int d[2000],vis[2000],cost[2000];
    int S,T,cnt;
    
    void spfa()
    {
        for(int i=0;i<=N;i++)
        {vis[i]=0;d[i]=INF;cost[i]=INF;}
        vis[S]=1;d[S]=0;cost[S]=0;
        queue<int> q;
        q.push(S);
        while(!q.empty())
        {
            int v=q.front();
            q.pop();vis[v]=0;
            int k=head[v];
            while(k!=-1)
            {
                int b=edge[k].t;
                if(d[b]>d[v]+edge[k].c)
                {
                    cost[b]=cost[v]+edge[k].q;
                    d[b]=d[v]+edge[k].c;
                    if(!vis[b])
                    {
                        vis[b]=1;
                        q.push(b);
                    }
                }
                else if(d[b]==d[v]+edge[k].c&&cost[b]>cost[v]+edge[k].q)
                {
                    cost[b]=cost[v]+edge[k].q;
                    if(!vis[b])
                    {
                        vis[b]=1;
                        q.push(b);
                    }
                }
                k=next1[k];
            }
        }
        
    }
    
    void Add(int a,int b,int c,int q)
    {
        edge[cnt].s=a;edge[cnt].t=b;
        edge[cnt].c=c;edge[cnt].q=q;
        next1[cnt]=head[edge[cnt].s];
        head[edge[cnt].s]=cnt;
        cnt++;
    }
    
    int main()
    {
        while(scanf("%d%d",&N,&M)!=-1)
        {
            if(!N&&!M) break;
            memset(head,-1,sizeof(head));
            cnt=1;
            for(int i=1;i<=M;i++)
            {
                int a,b,c,q;
                scanf("%d%d%d%d",&a,&b,&c,&q);
                Add(a,b,c,q);
                Add(b,a,c,q);
            }
            scanf("%d%d",&S,&T);
            spfa();
            printf("%d %d
    ",d[T],cost[T]);
        }
        return 0;
    }
    View Code
     
     
     
  • 相关阅读:
    bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊(分块算法)
    hdu 3652 "B-number"(数位DP)
    数位DP+其他
    hdu 4352 "XHXJ's LIS"(数位DP+状压DP+LIS)
    CodeForces 55D "Beautiful numbers"(数位DP+离散化处理)
    洛谷 P1163"银行贷款"(二分)
    ZOJ-3872-Beauty of Array-思维
    洛谷P3951 小凯的疑惑
    CodeForces
    CodeForces
  • 原文地址:https://www.cnblogs.com/ACRykl/p/9103805.html
Copyright © 2020-2023  润新知