zoukankan      html  css  js  c++  java
  • 计算最短路和次短路条数

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1688

    题意:在给定有向图中查找最短路与次短路,如果(最短路+1==次短路)则输出(最短路条数+次短路条数),否则只输出最短路条数。

    思路:在最短路的松弛操作上做些判断和记录即可,具体看代码吧(有注释)。

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<string>
    #include<string.h>
    #include<map>
    #include<vector>
    #include<algorithm>
    #include<cmath>
    #include<iterator>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define MOD 100000007
    #define LL long long
    #define INF 0x3f3f3f3f
    const double pi = acos(-1.0);
    const int Maxn=50000;
    using namespace std;
    inline int scan()
    {
        int x=0,c=1;
        char ch=' ';
        while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
        while(ch=='-')c*=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();
        return x*c;
    }
    int tol;
    int head[1000*2];
    /*******************前向星存边**************************/ 
    struct edge{
        int to,next,w;
    }e[10000*2];
    void add(int start,int ed,int w){
        e[tol].to=ed;
        e[tol].w=w;
        e[tol].next=head[start];
        head[start]=tol++;
    }
    /******************优先队列优化 **************************/ 
    struct node{
        int start;
        int w,p;
        node(int start,int w,int p):start(start),w(w),p(p){}
        friend bool operator < (node a,node b){
            return a.w>b.w;
        }
    };
    priority_queue<node>Q;
    int cnt[2][1010];
    int dis[2][1010];
    bool vis[2][1010];
    void dij(int start,int ed){
        dis[0][start]=0;//最短路的起点距离初始化为0 
        cnt[0][start]=1;//最短路因为一定会有一条,所以更新为一 
        Q.push(node(start,0,0));
        while(!Q.empty()){
            node n2=Q.top();
            Q.pop();
            int p=n2.p;
            int s=n2.start;
            if(vis[p][s]) continue;//如果该状态下的以s为起点已经松弛过就不要再进行操作了,会影响结果 
            vis[p][s]=true;
            for(int i=head[s];i!=-1;i=e[i].next){
                int to=e[i].to;
                int w=e[i].w;
                if(dis[0][to]>dis[p][s]+w){//如果这条边会使从s到to变短,则更新s到to的最短路与次短路以及他们的条数 
                    
                    dis[1][to]=dis[0][to];//原先的最短路变成了次短路 
                    dis[0][to]=dis[p][s]+w;//更新最短路 
                    cnt[1][to]=cnt[0][to];//原先最短路条数变成次短路条数 
                    cnt[0][to]=cnt[p][s];//更新最短路条数 
                    Q.push(node(to,dis[0][to],0));//用这个s->to当前最短路去更新其他的路 
                    Q.push(node(to,dis[1][to],1));//同上 
                    
                }else if(dis[0][to]==dis[p][s]+w){//这条路径等于当前s->to最短路,则s->to最短路条数增加即可 
                    
                    cnt[0][to]+=cnt[p][s];
                
                }else if(dis[1][to]>dis[p][s]+w){//当前路径的路径长度大于最短路但是小于次短路//更新次短路即可 
                    
                    dis[1][to]=dis[p][s]+w;
                    cnt[1][to]=cnt[p][s];
                    Q.push(node(to,dis[1][to],1));
                    
                }else if(dis[1][to]==dis[p][s]+w){//同上 
                    
                    cnt[1][to]+=cnt[p][s];
                    
                }
            }
        }
    }
    int n,m;
    /********************************初始化*******************************/ 
    void clear(){
        tol=0;
        for(int i=0;i<=n;i++){
            dis[0][i]=dis[1][i]=INF*2;
        }
        mem(head,-1);
        mem(cnt,0);
        mem(vis,false);
        mem(e,0);
        while(!Q.empty()) Q.pop();
    }
    /*************************************main函数*****************************/ 
    int main(){
        std::ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            int start,ed,w;
            cin>>n>>m;
            clear();
            for(int i=0;i<m;i++){
                cin>>start>>ed>>w;
                add(start,ed,w);
            }
            int s,f;
            cin>>s>>f;
            dij(s,f);
    //        cout<<dis[0][f]<<"  "<<dis[1][f]<<endl;
    //        cout<<cnt[0][f]<<"  "<<cnt[1][f]<<endl;
            int ans=cnt[0][f];
            if(dis[0][f]+1==dis[1][f]){
                ans+=cnt[1][f];
            }
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Java Object part1
    StringBuffer StringBuilder append
    Java equal
    java Classloader
    Java NIO
    Oracle中Blob和Clob
    Java8 Lambda 表达式
    HashMap分析 + 哈希表
    android自定义控件之滚动广告条
    android自定义控件之模仿优酷菜单
  • 原文地址:https://www.cnblogs.com/liuzuolin/p/10712754.html
Copyright © 2011-2022 走看看