题目大意:

希望求出走出最短路的方法总数,如果次短路只比最短路小1,那也是可取的

输出总的方法数

这里n个点,每个点有最短和次短两种长度

这里采取的是dijkstra的思想,相当于我们可以不断找到更新到的最短长度来更新其他长度,保证之前的所有可取的最短长度都已经更新的情况下,这样是除了第一个点的最短路为0已知,还需要更新2*n-1次,如果从一个点的位置出发更新了其他点,那么这个位置就不再作为可更新点~~这里都是暴力找最优的可更新的点~~不知道如何做到像普通的dijkstra那种log级别的找点~~

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 #define N 1005
 7 #define M 10005
 8 #define clr(a,b) memset(a,b,sizeof(a))
 9 struct Edge{
10     int x,y,d,next;
11     Edge(int x=0,int y=0,int d=0,int next=0):x(x),y(y),d(d),next(next){}
12 }e[M<<1];
13 int first[N] , tot , n , m , s , t;
14 void add_edge(int x,int y,int d)
15 {
16     e[tot] = Edge(x,y,d,first[x]);
17     first[x] = tot++;
18 }
19 int dis[N][2] , cnt[N][2] , vis[N][2];
20 void dijkstra(int s , int t)
21 {
22     clr(dis,0x3f);clr(vis,0);clr(cnt,0);
23     dis[s][0]=0;cnt[s][0]=1;
24     for(int i=1;i<2*n;i++){
25         int a=0 , b=0 , curd=0x7fffffff;
26         for(int j=1;j<=n;j++){
27             if(dis[j][0]<curd && !vis[j][0]) curd=dis[j][0] , a=j,b=0;
28             if(dis[j][1]<curd && !vis[j][1]) curd=dis[j][1] , a=j,b=1;
29         }
30        // cout<<a<<" "<<b<<" "<<curd<<endl;
31         vis[a][b]=1;
32         for(int i=first[a];~i;i=e[i].next){
33             int v = e[i].y , nowd=curd+e[i].d;
34             if(nowd<dis[v][0]){
35                 dis[v][1]=dis[v][0];cnt[v][1]=cnt[v][0];
36                 dis[v][0]=nowd;cnt[v][0]=cnt[a][b];
37             }
38             else if(nowd == dis[v][0]){
39                 cnt[v][0]+=cnt[a][b];
40             }
41             else if(nowd <dis[v][1]){
42                 dis[v][1]=nowd ;cnt[v][1]=cnt[a][b];
43             }
44             else if(nowd==dis[v][1]){
45                 cnt[v][1]+=cnt[a][b];
46             }
47         }
48     }
49   //  cout<<cnt[t][0]<<" "<<cnt[t][1]<<endl;
50     if(dis[t][1]-1 == dis[t][0]) cnt[t][0]+=cnt[t][1];
51     printf("%d\n" , cnt[t][0]);
52 }
53 int main()
54 {
55    // freopen("a.in" , "r" , stdin);
56     int T;
57     scanf("%d" , &T);
58     while(T--){
59         scanf("%d%d" , &n , &m);
60         clr(first,-1);tot=0;
61         for(int i=0; i<m ; i++){
62             int x,y,d;
63             scanf("%d%d%d" , &x,  &y , &d);
64             add_edge(x , y , d);
65         }
66 
67         scanf("%d%d" , &s , &t);
68         dijkstra(s,t);
69     }
70 
71     return 0;
72 }

 

 posted on 2016-03-28 21:55  Love风吟  阅读(498)  评论(0编辑  收藏  举报