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;
    }
  • 相关阅读:
    js截取字符串区分汉字字母代码
    List 去处自定义重复对象方法
    63. Unique Paths II
    62. Unique Paths
    388. Longest Absolute File Path
    41. First Missing Positive
    140. Word Break II
    139. Word Break
    239. Sliding Window Maximum
    5. Longest Palindromic Substring
  • 原文地址:https://www.cnblogs.com/liuzuolin/p/10712754.html
Copyright © 2011-2022 走看看