题意:给定n个点(点标[0,n-1])m条有向边,起点和终点
问次短路的条数(一定存在次短路权值>最短路)
记录每个点的最短路,次短路的长度和方法数
则当更新最短路时就要把旧的最短路路径赋给次短路,剩下的状态转移还是比较明显的
而所有可转移的点中优先转移先更新最近的点。则如此更新有些类似bfs更新过就不再更新该点。
因为给出的图中所有边{u,v,dis},u<v ;
必然无环且有一定偏序关系,则必须先更新点标小的点。
#include <stdio.h> #include <string.h> #include <iostream> #include <queue> #include <set> #include <vector> using namespace std; #define ll int #define inf 100000000 #define N 55 struct Edge{ int from, to, dis, nex; }edge[N*N*2]; int head[N], edgenum ; void add(int u, int v, int d){ Edge E={u,v,d,head[u]}; edge[edgenum] = E; head[u] = edgenum++; } int dis[N][2], dp[N][2]; int n, m, s, t; bool inq[N][2]; struct node{ int to, flag, dis; node(int a=0,int b=0,int c=0):to(a),flag(b),dis(c){} bool operator<(const node&a)const{ if(a.dis==dis)return a.to<to; return a.dis<dis; } }; void spfa(){ int i, j; memset(dp, 0, sizeof(dp)); memset(inq, 0, sizeof(inq)); for(j=0;j<=n;j++)dis[j][0] = dis[j][1] = inf; priority_queue<node>q; q.push(node(s,0,0)); dis[s][0] = 0; dp[s][0] = 1; while(!q.empty()){ node u = q.top(); q.pop(); if(inq[u.to][u.flag])continue; inq[u.to][u.flag] = 1; for(int i = head[u.to]; ~i; i = edge[i].nex){ int v = edge[i].to; int nowd = u.dis+edge[i].dis; if(!inq[v][0] && nowd < dis[v][0]) { if(dis[v][0]<inf) { dis[v][1] = dis[v][0]; dp[v][1] = dp[v][0]; q.push(node(v,1,dis[v][1])); } dis[v][0] = nowd; dp[v][0] = dp[u.to][u.flag]; q.push(node(v,0,dis[v][0])); } else if(!inq[v][0] && nowd == dis[v][0]) { dp[v][0] += dp[u.to][u.flag]; } else if(!inq[v][1] && nowd < dis[v][1]) { dis[v][1] = nowd; dp[v][1] = dp[u.to][u.flag]; q.push(node(v,1,dis[v][1])); } else if(!inq[v][1] && nowd == dis[v][1]) { dp[v][1] += dp[u.to][u.flag]; } } } } void init(){memset(head, -1, sizeof(head));edgenum = 0;} int main(){ ll u, v, d; while(~scanf("%d %d %d %d",&n,&m,&s,&t)){ init(); while(m--){ scanf("%d %d %d",&u,&v,&d); add(u,v,d); } spfa(); printf("%d %d\n", dis[t][1], dp[t][1]); } return 0; } /* 3 3 0 2 0 2 5 0 1 4 1 2 2 8 28 0 7 0 1 1 0 2 2 0 3 3 0 4 4 0 5 5 0 6 6 0 7 6 1 2 1 1 3 2 1 4 3 1 5 4 1 6 5 1 7 6 2 3 1 2 4 2 2 5 3 2 6 4 2 7 5 3 4 1 3 5 2 3 6 3 3 7 4 4 5 1 4 6 2 4 7 3 5 6 1 5 7 2 6 7 1 5 6 0 4 0 1 1 0 2 1 2 1 0 1 3 0 1 4 1 3 4 0 6 8 0 4 0 1 1 0 2 1 2 1 0 1 3 0 1 4 1 3 4 0 2 5 0 5 1 0 */