HDU1688(Sightseeing)

题目链接:传送门

题目大意:给你一幅图(单向边),找出从起点到终点有多少条不同路径(最短路或者比最短路长度大1)

题目思路:二维dijkstra,真的是要对dijkstra理解非常透彻才行,距离数组d开成二维表示最短路与次短路,同时需要一个cnt数组,记录有多少条路径

    对于当前点有四种更新情况:

    1.if(距离<最短路) 更新最短路与次短路(包括路径数)

    2.if(距离==最短路) 更新最短路路径数

    3.if(距离<次小) 更新次短路(包括路径数)

    4.if(距离==距离) 更新次短路路径数

    

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cctype>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <climits>
#define lson root<<1,l,mid
#define rson root<<1|1,mid+1,r
#define fi first
#define se second
#define seg int root,int l,int r
#define ping(x,y) ((x-y)*(x-y))
#define mst(x,y) memset(x,y,sizeof(x))
#define mcp(x,y) memcpy(x,y,sizeof(y))
#define Min(x,y) (x<y?x:y)
#define Max(x,y) (x>y?x:y)
using namespace std;
#define gamma 0.5772156649015328606065120
#define MOD 100000007
#define inf 0x3f3f3f3f
#define N 1005
#define maxn 10001000
typedef long long LL;
typedef pair<int,int> PII;

int n,x,y;
int vis[N][2],d[N][2];
int cnt[N][2];  
int head[N];
struct Node{
    int to,next,v;
    Node(int a=0,int b=0,int c=0){
        to=a; next=b; v=c;
    }
}node[N*10]; int ncnt;
struct Edge{
    int x,v,fl;
    Edge(int a=0,int b=0,int c=0):x(a),v(b),fl(c){}
    bool operator<(const Edge &a)const{
        return v>a.v;
    }
}temp,edge;
inline void add(int x,int y,int v){
    node[ncnt]=Node(y,head[x],v);
    head[x]=ncnt++;
}

void dijkstra(){
    mst(vis,0);
    mst(d,inf);
    mst(cnt,0);
    cnt[x][0]=1;
    d[x][0]=0;
    priority_queue<Edge>q;
    q.push(Edge(x,0,0));
    while(!q.empty()){
        edge=q.top();q.pop();
        if(vis[edge.x][edge.fl]) continue;
        int s=edge.x;
        int flag=edge.fl;
        vis[s][flag]=1;
        for(int i=head[s];~i;i=node[i].next){
            int e=node[i].to;
            if(d[e][0]>node[i].v+d[s][flag]){  ///更新最短路与次短路
                if(d[e][1]>d[e][0]){
                    d[e][1]=d[e][0];
                    cnt[e][1]=cnt[e][0];
                    q.push(Edge(e,d[e][1],1));
                }
                d[e][0]=node[i].v+d[s][flag];
                cnt[e][0]=cnt[s][flag];
                q.push(Edge(e,d[e][0],0));
            }
            else if(d[e][0]==node[i].v+d[s][flag]){ ///更新最短路路径数
                cnt[e][0]+=cnt[s][flag];
            }
            else if(d[e][1]>node[i].v+d[s][flag]){  ///更新次短路
                d[e][1]=node[i].v+d[s][flag];
                cnt[e][1]=cnt[s][flag];  
                q.push(Edge(e,d[e][1],1));
            }
            else if(d[e][1]==node[i].v+d[s][flag]){  ///更新次短路路径数
                cnt[e][1]+=cnt[s][flag]; 
            }
        }
    }
}

int main(){
    int i,j,group,k,m,v;
    scanf("%d",&group);
    while(group--){
        mst(head,-1);
        ncnt=0;
        scanf("%d%d",&n,&m);
        while(m--){
            scanf("%d%d%d",&x,&y,&v);
            add(x,y,v);
        }
        scanf("%d%d",&x,&y);
        dijkstra();
        int ans=cnt[y][0];
        if(d[y][0]+1==d[y][1]) ans+=cnt[y][1];
        printf("%d
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Kurokey/p/5443637.html