求最短路数量和和次短路与最短路长度大于1的途径数量。 原来想用第K短路把所有的前面最短的和次短(K=1,2,3,,,,)最后TLE了,不知道A*的复杂度是多少,然后的得用次短路求解,用dp[][2]数组存顶点遍历的次数, Source Code Problem: 3463 User: 1013101127 Memory: 852K Time: 516MS Language: G++ Result: Accepted Source Code #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <algorithm> using namespace std; const int INF=9999999; struct node { int v; int len; int next; }edge[10005]; bool cmp(node a,node b) { return a.len<b.len; } int cnt; int head[1003]; int n,m; int start; int end; void init() { for(int i=1;i<=n;i++) head[i]=-1; cnt=0; } void insert(int u,int v,int len) { edge[cnt].v=v;edge[cnt].len=len;edge[cnt].next=head[u]; head[u]=cnt; cnt++; } int disj(int S,int E) { int i,j; int v[1002][2]; int dis[1002][2]; int dp[1002][2];//记录顶点遍历的次数,次短路的模版没有这个, memset(v,0,sizeof(v)); memset(dp,0,sizeof(dp)); for(i = 1;i <= n;i ++) dis[i][0] = dis[i][1] = INF; dis[S][0] = 0; dp[S][0] = 1; int x,flag; for(i = 1;i <= n*2;i ++) { int min_d = INF; for(j = 1;j <= n;j ++) { if(!v[j][0] && min_d > dis[j][0]) { min_d = dis[j][0]; x = j; flag = 0; } else if(!v[j][1] && min_d > dis[j][1]) { min_d = dis[j][1]; x = j; flag = 1; } } v[x][flag] = 1; if(min_d == INF) break; for(j = head[x];j != -1;j = edge[j].next) { int len = min_d + edge[j].len,y = edge[j].v; if(len < dis[y][0]) { dis[y][1] = dis[y][0]; dp[y][1] = dp[y][0]; dis[y][0] = len; dp[y][0] = dp[x][flag]; } else if(len == dis[y][0]) { dp[y][0] += dp[x][flag]; } else if(len < dis[y][1]) { dis[y][1] = len; dp[y][1] = dp[x][flag]; } else if(len == dis[y][1]) { dp[y][1] += dp[x][flag]; } } } int ans; if(dis[E][0]+1==dis[E][1])//最短路和次短路差一 ans=dp[E][0]+dp[E][1]; else ans=dp[E][0]; return ans; } int main() { int cas; int uu,vv,L; cin>>cas; while(cas--) { cin>>n>>m; init(); for(int i=1;i<=m;i++) { cin>>uu>>vv>>L; insert(uu,vv,L); } cin>>start>>end; cout<<disj(start,end)<<endl; } return 0; }