zoukankan      html  css  js  c++  java
  • hdu3191+hdu1688(求最短路和次短路条数,模板)

    hdu3191题意:求出次短路的长度和条数

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    using namespace std;
    const int MAXN=55;
    const int inf=1<<30;
    struct Edge{
        int v,w;
    };
    vector<Edge>vet[MAXN];
    struct Node{
        int v,dist;
        int mark;//标记,1为最短路,2为次短路;
        bool operator < (const Node &p) const {
            if(p.dist!=dist)
                return p.dist<dist;
    
            return p.v<v;//这儿如果不按顶点的大小排序,就wa了。
        }
    };
    int n,m,s,e;
    int dist[MAXN][3];
    int dp[MAXN][3];
    bool visited[MAXN][3];
    //dp[i][1]表示到达点i最短的路有多少条,dp[i][2]表示次短的条数  
    //dist[i][1]表示到达点i最短路的长度,dist[i][2]表示次短路的长度
    /*
    用v去松驰u时有四种情况 (设当前dist[v][cas]) 
    情况1:dist[v][cas]+w(v,u)<dist[u][1],找到一个更短的距离,则把原来最短的距离作为次短的距离,同时更新最短的.即
    dist[u][2]=dist[u][1]   
    dist[u][1]=dist[v][cas]+w(v,u);   
    dp[u][2]=dp[u][1]   
    dp[u][1]=dp[v][cas], 
    把Node(dist[u][1],u,1)和Node(dist[u][2],u,2)放入队列 
    情况2:dist[v][cas]+w(v,u)==dist[u][1],找到一条新的相同距离的最短路,则dp[u][1]+=dp[v][cas],其他不用更新,也不入队 
    情况3:dist[v][cas]+w(v,u)<dist[u][2],不可以更新最短距离,但可以更新次短的,则更新dist[u][2]和dp[u][2]  
    dist[u][2]=dist[v][cas]+w(v,u);  
    dp[u][2]=dp[v][cas]; 
    把Node(dist[u][2],u,2)放入队列 
    情况4:dist[v][cas]+w(v,u)==dist[u][2] 找到一条新的相同距离的次短路,则dp[u][2]+=dp[v][cas],其他不更新。 
    */
    
    
    
    void Dijkstra(int start,int end){
        for(int i=0;i<n;i++){
            dist[i][1]=dist[i][2]=inf;
        }
        memset(dp,0,sizeof(dp));
        memset(visited,false,sizeof(visited));
        priority_queue<Node>Q;
        Node p,q;
        dist[start][1]=0;
        dp[start][1]=1;
        p.dist=0,p.mark=1,p.v=start;
        Q.push(p);
        while(!Q.empty()){
            p=Q.top();
            Q.pop();
            if(visited[p.v][p.mark])continue;
            //if(dist[p.v][p.mark]!=p.dist)continue;
            visited[p.v][p.mark]=true;
            for(int i=0;i<vet[p.v].size();i++){
                int v=vet[p.v][i].v;
                int w=vet[p.v][i].w;
                if(!visited[v][1]&&p.dist+w<dist[v][1]){
                    //可能为次短路
                    if(dist[v][1]!=inf){
                        q.v=v,q.dist=dist[v][1],q.mark=2;
                        dist[v][2]=dist[v][1];
                        dp[v][2]=dp[v][1];
                        Q.push(q);
                    }
                    dist[v][1]=p.dist+w;
                    dp[v][1]=dp[p.v][p.mark];
                    q.v=v,q.dist=dist[v][1],q.mark=1;
                    Q.push(q);
                }else if(!visited[v][1]&&p.dist+w==dist[v][1]){
                    dp[v][1]+=dp[p.v][p.mark];
                }else if(!visited[v][2]&&p.dist+w<dist[v][2]){
                    dist[v][2]=p.dist+w;
                    dp[v][2]=dp[p.v][p.mark];
                    q.dist=dist[v][2],q.v=v,q.mark=2;
                    Q.push(q);
                }else if(!visited[v][2]&&p.dist+w==dist[v][2]){
                    dp[v][2]+=dp[p.v][p.mark];
                }
            }
        }
    }
    
    
    
    int main(){
        while(~scanf("%d%d%d%d",&n,&m,&s,&e)){
            for(int i=0;i<n;i++)vet[i].clear();
            for(int i=1;i<=m;i++){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                Edge p;
                p.v=v,p.w=w;
                vet[u].push_back(p);
            }
            Dijkstra(s,e);
            printf("%d %d
    ",dist[e][2],dp[e][2]);
        }
        return 0;
    }
    

     hdu1688

    题意:求出最短路的条数比最短路大1的次短路的条数和,基本和上题一样,只是最后多了一个判断是否dist[e][1]+1==dist[e][2];

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<queue>
    using namespace std;
    const int MAXN=1000+10;
    const int inf=1<<30;
    struct Edge{
        int v,w;
    };
    vector<Edge>vet[MAXN];
    struct Node{
        int v,dist;
        int mark;
        bool operator < (const Node &p)const {
            return p.dist<dist;
        }
    };
    int dist[MAXN][3];
    int dp[MAXN][3];
    bool visited[MAXN][3];
    int n,m,s,e;
    
    
    void Dijkstra(int start,int end){
        for(int i=1;i<=n;i++){
            dist[i][1]=dist[i][2]=inf;
        }
        memset(visited,false,sizeof(visited));
        memset(dp,0,sizeof(dp));
        dist[start][1]=0;
        dp[start][1]=1;
        priority_queue<Node>Q;
        Node p,q;
        p.dist=0,p.mark=1,p.v=start;
        Q.push(p);
        while(!Q.empty()){
            p=Q.top();
            Q.pop();
            if(visited[p.v][p.mark])continue;
            visited[p.v][p.mark]=true;
            for(int i=0;i<vet[p.v].size();i++){
                int v=vet[p.v][i].v;
                int w=vet[p.v][i].w;
                if(!visited[v][1]&&p.dist+w<dist[v][1]){
                    if(dist[v][1]!=inf){
                        dist[v][2]=dist[v][1];
                        dp[v][2]=dp[v][1];
                        q.v=v,q.dist=dist[v][2],q.mark=2;
                        Q.push(q);
                    }
                    dist[v][1]=p.dist+w;
                    dp[v][1]=dp[p.v][p.mark];
                    q.dist=dist[v][1],q.v=v,q.mark=1;
                    Q.push(q);
                }else if(!visited[v][1]&&p.dist+w==dist[v][1]){
                    dp[v][1]+=dp[p.v][p.mark];
                }else if(!visited[v][2]&&p.dist+w<dist[v][2]){
                    dist[v][2]=p.dist+w;
                    dp[v][2]=dp[p.v][p.mark];
                    q.v=v,q.dist=dist[v][2],q.mark=2;
                    Q.push(q);
                }else if(!visited[v][2]&&p.dist+w==dist[v][2]){
                    dp[v][2]+=dp[p.v][p.mark];
                }
            }
        }
    }
    
    
    int main(){
        int _case;
        scanf("%d",&_case);
        while(_case--){
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++)vet[i].clear();
            for(int i=1;i<=m;i++){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                Edge p;
                p.v=v,p.w=w;
                vet[u].push_back(p);
            }
            scanf("%d%d",&s,&e);
            Dijkstra(s,e);
            if(dist[e][1]+1==dist[e][2]){
                printf("%d
    ",dp[e][1]+dp[e][2]);
            }else 
                printf("%d
    ",dp[e][1]);
        }
        return 0;
    }
    
  • 相关阅读:
    volatile关键字——确保本指令不会因编译器的优化而省略
    c#判断字符串是否为空或null
    python+selenium基础之XPATH轴定位
    python+selenium基础之XPATH定位
    在python中使用正则表达式
    selenium 的css选择器语法
    selenium用法详解
    selenium+requests进行cookies保存读取操作
    Python selenium 三种等待方式详解
    selenium 显示等待应用
  • 原文地址:https://www.cnblogs.com/ziyi--caolu/p/3470073.html
Copyright © 2011-2022 走看看