SPFA+寻路(行路难,洛谷2832)

SPFA加寻路的操作只需要多添加一个数组记录路径即可。

我们把这个数组叫做G数组,G数组里的数要求满足SPFA的判断条件时才会执行。也就是SPFA路径。

1 void find(int x)
2 {
3     if(G[x]==0){
4         printf("%d ",1);
5         return;
6     }
7     find( G[x] );
8     printf("%d ",x);
9 }

通过这个函数查询每个点的钱一个路径,因为1号点没有前一个路径,所以好手动输出。

具体操作以洛谷2832为例:http://www.luogu.org/problem/show?pid=2832

第17行为G数组的定义,61行为G数组的应用,在SPFA条件满足的时候,我们就把G数组的值进行了更改。最后通过71行的函数进行查询即可。

关于这道题还有一个难点就是疲劳值:因为疲劳值是每走一条路径再走任意一条路径都会增加1,但是如果每次都对所有的边进行修改,那时间复杂度和难度都很现实,所有我们采取曲线救国的思想,对当前的点添加一个疲劳值,从这个点向外走的话,我们就要加上这个疲劳值 ( dis[当前点] + edge[i].val +fit[当前点] < dis[ 指向点 ] )dis就是从原点开始到当前点的距离,edge[i].val就是权值,再加上当前点fit(疲劳值)如果还是小于下一个点的距离的话,我们就替换,相比以前的SPFA多加了一个fit。

fit的计算方法为:fit[指向点]=fit[当前点]+1;只要满足SPFA的条件就执行,不要在意会不会覆盖掉之前的,因为这是最近的点的fit,就算之前的比这个小,但是你的总体值是比之前的总体值小的,如果当前值不会的话,会在后期的SPFA判断里从新修改,所以不用担心覆盖之前的值。

具体剩下的看代码就好。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 using namespace std;
 6 #define MAX 10005
 7 #define MAXM 200005
 8 //==============================================================================
 9 struct NODE{
10     int point,val,next_edge;
11     int last_spot;
12     NODE(){ next_edge=0;
13             last_spot=0;
14          }
15     }edge[MAXM];
16 //==============================================================================
17 int N,M,G[MAX],fit[MAX];//疲劳值和路径
18 queue<int> que;
19 int edgenum=0,link[MAX],vister[MAX],dis[MAX];
20 //==============================================================================
21 void intit();
22 void ADD(int ,int ,int);
23 void SPFA();
24 void find(int);
25 //==============================================================================
26 void init()
27 {
28     memset( dis , 0x3f3f3f3f , sizeof(dis) );
29     int aa,bb,cc;
30     cin>>N>>M;
31     for(int i=1;i<=M;i++){
32         scanf("%d%d%d*c",&aa,&bb,&cc);
33         ADD( aa , bb , cc );
34     }
35 }
36 //==============================================================================
37 void ADD(int last, int next,int val)
38 {
39     edgenum++;
40     edge[edgenum].point=next;
41     edge[edgenum].val=val;
42     edge[edgenum].next_edge=link[last];
43     link[last]=edgenum;
44 }
45 //==============================================================================
46 void SPFA()
47 {
48     que.push(1);
49     vister[1]=1;
50     dis[1]=0;
51     //============================
52     while(!que.empty()){
53         int temp=que.front();
54         que.pop();
55         vister[temp]=0;
56         //=========================
57         for(int i=link[temp]; i!=0 ; i=edge[i].next_edge ){
58             if( dis[temp] + edge[i].val +fit[temp] < dis[ edge[i].point ] ){
59                 dis[ edge[i].point ]=dis[temp]+edge[i].val+fit[temp];
60                 fit[edge[i].point]=fit[temp]+1;
61                 G[ edge[i].point ]=temp;
62                 if( vister[ edge[i].point ] == 0 ){
63                     vister[edge[i].point]=1;
64                     que.push(edge[i].point);
65                 }
66             }
67         }
68     }
69 }
70 //==============================================================================
71 void find(int x)
72 {
73     if(G[x]==0){
74         printf("%d ",1);
75         return;
76     }
77     find( G[x] );
78     printf("%d ",x);
79 }
80 //==============================================================================
81 int main()
82 {
83     init();
84     SPFA();
85     printf("%d\n",dis[N]);
86     find(N);
87     //system("pause");
88     return 0 ;
89 }

 

posted on 2016-09-30 09:56  fuyun_boy  阅读(466)  评论(0编辑  收藏  举报

导航