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;
}




 

posted @ 2016-04-18 10:31  zhangxianlong  阅读(97)  评论(0编辑  收藏  举报