题目链接:http://poj.org/problem?id=3463
给定一有向图,要你求出最短路的数目和最短路长度+1的数目。
比较方便的办法就是在Dijkstra的时候就直接把数目求出来,Dijkstra基于贪心的思想,一个点向其它点松弛后,那么就不会有后继点向此点松弛,因此可以来统计总共有多少条路径:1,更新v点最短距离后,v点路径数目等于u点路径数目 2,如果到点u到点v有等于v点当前的最短路径,则v点的路径数目加上u点的路径数目。求最短路长度+1的数目实际上就是求次短路的数目,如果次短路长度刚好比最短路长度大1,那么就是答案的一部分。注意到这个次短路比较特殊,之比最短路大1,因此次短路的前继节点距离只可能是最短的或者次短的,因此可以用d[N][2],cou[N][2],来统计:
1,如果d[u][0]+w<d[u][0],分别更新v点的最短路和次短路
2,如果d[u][0]+w==d[u][0],那么v点的最短路数加上u点的最短路数
3,如果d[u][k]+w<d[u][1],更新v点的次短路数(根据k来定)
4,如果d[u][k]+w==d[u][1],那么v点的次短路数加上u点的最短路数或者次短路数(根据k来定)
最短路长度+1的数目还可以用记忆化搜索来求解,转移方程:f[u]=sum{f[v] | d[u]-w=d[v]} + sum{cou[v] | d[u]-w+1=d[v]}。要注意建立反向边!
Dijkstra+记忆化搜索:
1 //STATUS:C++_AC_32MS_532KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector> 10 #include<queue> 11 #include<stack> 12 using namespace std; 13 #define LL __int64 14 #define pii pair<int,int> 15 #define Max(a,b) ((a)>(b)?(a):(b)) 16 #define Min(a,b) ((a)<(b)?(a):(b)) 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define lson l,mid,rt<<1 19 #define rson mid+1,r,rt<<1|1 20 const int N=1010,M=1000000,INF=0x3f3f3f3f,MOD=1999997; 21 const LL LLNF=0x3f3f3f3f3f3f3f3fLL; 22 const double DNF=100000000; 23 24 struct Edge{ 25 int u,v,w; 26 }e[N*10*2]; 27 int first[N],next[N*10*2],d[N],cou[N],cou2[N]; 28 int T,s,f,n,m,mt; 29 30 void adde(int a,int b,int c) 31 { 32 e[mt].u=a,e[mt].v=b;e[mt].w=c; 33 next[mt]=first[a],first[a]=mt++; 34 e[mt].u=b,e[mt].v=a;e[mt].w=c; 35 next[mt]=first[b],first[b]=mt++; 36 } 37 38 int dijkstra(int s) 39 { 40 int i,u; 41 pii t; 42 priority_queue<pii,vector<pii>,greater<pii> > q; 43 mem(d,0x3f);d[s]=0; 44 cou[s]=1; 45 q.push(make_pair(d[s],s)); 46 while(!q.empty()){ 47 t=q.top();q.pop(); 48 u=t.second; 49 if(t.first!=d[u])continue; 50 for(i=first[u];i!=-1;i=next[i]){ 51 if((i&1)==0)continue; 52 if(d[u]+e[i].w<d[e[i].v]){ 53 cou[e[i].v]=cou[u]; 54 d[e[i].v]=d[u]+e[i].w; 55 q.push(make_pair(d[e[i].v],e[i].v)); 56 } 57 else if(d[u]+e[i].w==d[e[i].v])cou[e[i].v]+=cou[u]; 58 } 59 } 60 return 1; 61 } 62 63 int dfs(int u) 64 { 65 if(cou2[u]!=-1)return cou2[u]; 66 cou2[u]=0; 67 int i; 68 for(i=first[u];i!=-1;i=next[i]){ 69 if(i&1)continue; 70 if(d[u]-e[i].w==d[e[i].v]) 71 cou2[u]+=dfs(e[i].v); 72 else if(d[u]-e[i].w+1==d[e[i].v]) 73 cou2[u]+=cou[e[i].v]; 74 } 75 return cou2[u]; 76 } 77 78 int main() 79 { 80 // freopen("in.txt","r",stdin); 81 int i,j,a,b,c,ans; 82 scanf("%d",&T); 83 while(T--) 84 { 85 mt=0; 86 mem(first,-1); 87 mem(cou2,-1); 88 scanf("%d%d",&n,&m); 89 for(i=0;i<m;i++){ 90 scanf("%d%d%d",&a,&b,&c); 91 adde(a,b,c); 92 } 93 scanf("%d%d",&s,&f); 94 95 dijkstra(f); 96 ans=cou[s]; 97 ans+=dfs(s); 98 99 printf("%d\n",ans); 100 } 101 return 0; 102 }
Dijkstra:
1 //STATUS:C++_AC_47MS_964KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector> 10 #include<queue> 11 #include<stack> 12 using namespace std; 13 #define LL __int64 14 #define pii pair<int,int> 15 #define Max(a,b) ((a)>(b)?(a):(b)) 16 #define Min(a,b) ((a)<(b)?(a):(b)) 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define lson l,mid,rt<<1 19 #define rson mid+1,r,rt<<1|1 20 const int N=1010,M=1000000,INF=0x3f3f3f3f,MOD=1999997; 21 const LL LLNF=0x3f3f3f3f3f3f3f3fLL; 22 const double DNF=100000000; 23 24 struct Node{ 25 int d,u,flag; 26 bool operator < (const Node &oth) const{ 27 return d>oth.d; 28 } 29 }; 30 struct Edge{ 31 int u,v,w; 32 }e[N*10]; 33 int first[N],next[N*10],d[N][2],cou[N][2]; 34 int T,s,f,n,m,mt; 35 36 void adde(int a,int b,int c) 37 { 38 e[mt].u=a,e[mt].v=b;e[mt].w=c; 39 next[mt]=first[a],first[a]=mt++; 40 } 41 42 int dijkstra(int s) 43 { 44 int i,u,v,w,k,dis; 45 Node t; 46 priority_queue<Node> q; 47 mem(d,0x3f);d[s][0]=d[s][1]=0; 48 cou[s][0]=cou[s][1]=1; 49 t.d=0,t.u=s,t.flag=0; 50 q.push(t); 51 while(!q.empty()){ 52 t=q.top();q.pop(); 53 u=t.u;dis=t.d;k=t.flag; 54 if(dis!=d[u][k])continue; 55 for(i=first[u];i!=-1;i=next[i]){ 56 v=e[i].v;w=e[i].w; 57 if(dis+w<d[v][0]){ 58 cou[v][1]=cou[v][0]; 59 cou[v][0]=cou[u][0]; 60 d[v][1]=d[v][0]; 61 d[v][0]=dis+w; 62 q.push(Node{d[v][0],v,0}); 63 q.push(Node{d[v][1],v,1}); 64 } 65 else if(dis+w==d[v][0])cou[v][0]+=cou[u][0]; 66 else if(dis+w<d[v][1]){ 67 d[v][1]=dis+w; 68 cou[v][1]=cou[u][k]; 69 q.push(Node{d[v][1],v,1}); 70 } 71 else if(dis+w==d[v][1])cou[v][1]+=cou[u][k]; 72 } 73 } 74 return cou[f][0]+(d[f][1]==d[f][0]+1?cou[f][1]:0); 75 } 76 77 int main() 78 { 79 // freopen("in.txt","r",stdin); 80 int i,j,a,b,c; 81 scanf("%d",&T); 82 while(T--) 83 { 84 mt=0; 85 mem(first,-1); 86 scanf("%d%d",&n,&m); 87 for(i=0;i<m;i++){ 88 scanf("%d%d%d",&a,&b,&c); 89 adde(a,b,c); 90 } 91 scanf("%d%d",&s,&f); 92 93 printf("%d\n",dijkstra(s)); 94 } 95 return 0; 96 }