• hdu-1688次短路问题


    最近才听说次短路问题,以为挺简单其实是眼高手低,

    题目意思就是裸的次短路,问最短路的个数和与最短路差1的个数和,考虑dijkstra的特性,可以利用每次进队列的方式方式实现。

    朴素的dij就是进dis数列中的最小的,还要标记vis,那么次短路可以看做分类讨论

    首先开出最短路和次短路的dis,cnt,和vis,那么入队方式什么的都和朴素的一样,

    但是注意分类讨论,

    如果拿出来的是个最短路,就分情况看看是不是影响最短路,如果影响最短路,那么次短路也相应转移,所以把两个都入,

    如果不影响最短路,再判断是不是影响次短路,同理。

    如果拿出来的是个次短路,就分情况看看是不是影响次短路,同理。

    如果说dij是,似乎有些dp思想。。。

    太弱了,最近还习惯性手残。。。。继续努力。。。加油

    #include <iostream>
    #include <vector>
    #include <stdio.h>
    #include <queue>
    #include <cstring>
    #include <math.h>
    using namespace std;
    
    const int maxn=100005;
    int n,m,x,y;
    int dis[maxn][2];
    int cnt[maxn][2];
    int vis[maxn][2];
    struct edge{
        int x,val;
        edge(int a,int c):x(a),val(c){};
    };
    struct node{
        int x,y,val;
        node(int a,int b,int c):x(a),y(b),val(c){};
    };
    bool operator <(const node e1,const node e2){
        return e1.val>e2.val;
    }
    vector<edge> v[maxn];
    
    void dij(int x,int y){
        for(int i=0;i<=n;i++)
            dis[i][0]=dis[i][1]=1<<30;
        memset(vis,0,sizeof(vis));
        memset(cnt,0,sizeof(cnt));
        priority_queue<node> pq;
        dis[x][0]=0;
        cnt[x][0]=1;
        pq.push(node(x,0,0));
        while(!pq.empty()){
            node cs=pq.top();
            pq.pop();
            if(vis[cs.x][cs.y])continue;
            vis[cs.x][cs.y]=1;
            for(int i=0;i<v[cs.x].size();i++){
                if(cs.y==0){
                    if(dis[cs.x][0]+v[cs.x][i].val<=dis[v[cs.x][i].x][0]){
                        if(dis[cs.x][0]+v[cs.x][i].val==dis[v[cs.x][i].x][0]){
                            cnt[v[cs.x][i].x][0]+=cnt[cs.x][0];
                        }
                        else{
                            cnt[v[cs.x][i].x][1]=cnt[v[cs.x][i].x][0];
                            cnt[v[cs.x][i].x][0]=cnt[cs.x][0];
                            dis[v[cs.x][i].x][1]=dis[v[cs.x][i].x][0];
                            pq.push(node(v[cs.x][i].x,1,dis[v[cs.x][i].x][1]));
                        }
                        dis[v[cs.x][i].x][0]=dis[cs.x][0]+v[cs.x][i].val;
                        pq.push(node(v[cs.x][i].x,0,dis[v[cs.x][i].x][0]));
                    }
                    else if(dis[cs.x][0]+v[cs.x][i].val<=dis[v[cs.x][i].x][1]){
                        if(dis[cs.x][0]+v[cs.x][i].val==dis[v[cs.x][i].x][1]) cnt[v[cs.x][i].x][1]+=cnt[cs.x][0];
                        else cnt[v[cs.x][i].x][1]=cnt[cs.x][0];
                        dis[v[cs.x][i].x][1]=dis[cs.x][0]+v[cs.x][i].val;
                        pq.push(node(v[cs.x][i].x,1,dis[v[cs.x][i].x][1]));
                    }
                }
                else{
                    if(dis[cs.x][1]+v[cs.x][i].val<=dis[v[cs.x][i].x][1]){
                        if(dis[cs.x][1]+v[cs.x][i].val==dis[v[cs.x][i].x][1])cnt[v[cs.x][i].x][1]+=cnt[cs.x][1];
                        else cnt[v[cs.x][i].x][1]=cnt[cs.x][1];
                        dis[v[cs.x][i].x][1]=dis[cs.x][1]+v[cs.x][i].val;
                        pq.push(node(v[cs.x][i].x,1,dis[v[cs.x][i].x][1]));
                    }
                }
            }
        }
    }
    
    int main()
    {
        int t;
        cin>>t;
        while(t--){
            scanf("%d%d",&n,&m);
            int a,b,c;
            for(int i=0;i<=n;i++)
                v[i].clear();
            for(int i=0;i<m;i++){
                scanf("%d%d%d",&a,&b,&c);
                v[a].push_back(edge(b,c));
               
            }
            scanf("%d%d",&x,&y);
            dij(x,y);
            if(dis[y][0]+1==dis[y][1])
                cout<<cnt[y][1]+cnt[y][0]<<endl;
            else
                cout<<cnt[y][0]<<endl;
        }
        return 0;
    }




  • 相关阅读:
    SpringMVC之数据处理及跳转
    SpringMVC之控制器Controller和RestFul风格
    第一个SpringMVC程序
    什么是SpringMVC
    Spring声明式事务
    【嘎】字符串-反转字符串
    【嘎】字符串-字符串中的单词数
    【嘎】二叉树-226. 翻转二叉树
    【嘎】数组-面试题 01.07. 旋转矩阵-看题解
    【嘎】字符串-统计位数为偶数的数字
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672580.html
Copyright © 2020-2023  润新知