hdu-1688次短路问题

来源:互联网 发布:国外域名注册价格对比 编辑:程序博客网 时间:2024/06/05 08:19

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

题目意思就是裸的次短路,问最短路的个数和与最短路差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;}





0 0
原创粉丝点击