最短路和次短路问题,dijkstra算法
生活随笔
收集整理的這篇文章主要介紹了
最短路和次短路问题,dijkstra算法
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1 /*
2 ?*題目大意:
3 ?*在一個(gè)有向圖中,求從s到t兩個(gè)點(diǎn)之間的最短路和比最短路長1的次短路的條數(shù)之和;
4 ?*
5 ?*算法思想:
6 ?*用A*求第K短路,目測會超時(shí),直接在dijkstra算法上求次短路;
7 ?*將dist數(shù)組開成二維的,即dist[v][2],第二維分別用于記錄最短路和次短路;
8 ?*再用一個(gè)cnt二維數(shù)組分別記錄最短路和次短路的條數(shù);
9 ?*每次更新路徑的條數(shù)時(shí),不能直接加1,,應(yīng)該加上cnt[u][k],k為次短路徑或者最短路徑的標(biāo)記;
10 ?*圖有重邊,不能用鄰接矩陣存儲;
11 ?*不知道為什么,題目上說的是N and M, separated by a single space, with 2≤N≤1000 and 1 ≤ M ≤ 10000;
12 ?*而我的代碼硬是把N開成1W了才過,求解釋,RE了無數(shù)次,擦;
13 **/?
14 #include<iostream>?
15 #include<cstdio>?
16 #include<cstring>?
17 #include<string>?
18 #include<algorithm>?
19 using namespace std;?
20 ???
21 const int N=11111;?
22 const int M=111111;?
23 const int INF=0xffffff;?
24 ???
25 struct node?
26 {?
27 ????int to;?
28 ????int w;?
29 ????int next;?
30 };?
31 ???
32 node edge[N];?
33 int head[N];?
34 ???
35 int dist[N][2],cnt[N][2];?
36 bool vis[N][2];?
37 int n,m,s,t,edges;?
38 ???
39 void addedge(int u,int v,int w)?
40 {?
41 ????edge[edges].w=w;?
42 ????edge[edges].to=v;?
43 ????edge[edges].next=head[u];?
44 ????head[u]=edges++;?
45 }?
46 ???
47 int dijkstra()?
48 {?
49 ????int k;?
50 ????for(int i=0; i<=n; i++)?
51 ????{?
52 ????????dist[i][0]=dist[i][1]=INF;?
53 ????????vis[i][0]=vis[i][1]=0;?
54 ????????cnt[i][0]=cnt[i][1]=0;?
55 ????}?
56 ????cnt[s][0]=1,dist[s][0]=0;?
57 ???
58 ????for(int i=1; i<=n*2; i++)?
59 ????{?
60 ????????int u=-1;?
61 ????????int min_dist=INF;?
62 ????????for(int j=1; j<=n; j++)?
63 ????????????for(int flag=0; flag<2; flag++)?
64 ????????????????if(!vis[j][flag]&&dist[j][flag]<min_dist)?
65 ????????????????{?
66 ????????????????????min_dist=dist[j][flag];?
67 ????????????????????u=j;?
68 ????????????????????k=flag;?
69 ????????????????}?
70 ????????if(u==-1)?
71 ????????????break;?
72 ????????vis[u][k]=true;?
73 ????????for(int e=head[u]; e!=-1; e=edge[e].next)?
74 ????????{?
75 ????????????int j=edge[e].to;?
76 ????????????int tmp=dist[u][k]+edge[e].w;?
77 ???
78 ????????????if(tmp<dist[j][0])//tmp小于最短路徑長:?
79 ????????????{?
80 ????????????????dist[j][1]=dist[j][0];//次短路徑長?
81 ????????????????cnt[j][1]=cnt[j][0];//次短路徑計(jì)數(shù)?
82 ????????????????dist[j][0]=tmp;//最短路徑長?
83 ????????????????cnt[j][0]=cnt[u][k];//最短路徑計(jì)數(shù)?
84 ????????????}?
85 ???
86 ????????????else if(tmp==dist[j][0])//tmp等于最短路徑長:?
87 ????????????{?
88 ????????????????cnt[j][0]+=cnt[u][k];//最短路徑計(jì)數(shù)?
89 ????????????}?
90 ???
91 ????????????else if(tmp<dist[j][1])//tmp大于最短路徑長且小于次短路徑長:?
92 ????????????{?
93 ????????????????dist[j][1]=tmp;//次短路徑長?
94 ????????????????cnt[j][1]=cnt[u][k];//次短路徑計(jì)數(shù)?
95 ????????????}?
96 ???
97 ????????????else if(tmp==dist[j][1])//tmp等于次短路徑長:?
98 ????????????{?
99 ????????????????cnt[j][1]+=cnt[u][k];//次短路徑計(jì)數(shù)?
100 ????????????}?
101 ????????}?
102 ????}?
103 ???
104 ????int res=cnt[t][0];?
105 ????if(dist[t][0]+1==dist[t][1])//判斷最短路和次短路是否相差1?
106 ????????res+=cnt[t][1];?
107 ????return res;?
108 }?
109 ???
110 int main()?
111 {?
112 ????//freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin);?
113 ????int tcase;?
114 ????scanf("%d",&tcase);?
115 ????while(tcase--)?
116 ????{?
117 ????????edges=0;?
118 ????????scanf("%d%d",&n,&m);?
119 ????????memset(head,-1,sizeof(head));?
120 ????????int u,v,w;?
121 ????????for(int i=0; i<m; i++)?
122 ????????{?
123 ????????????scanf("%d%d%d",&u,&v,&w);?
124 ????????????addedge(u,v,w);?
125 ????????}?
126 ????????scanf("%d%d",&s,&t);?
127 ????????printf("%d\n",dijkstra());?
128 ????}?
129 ????return 0;?
130 }?
?
轉(zhuǎn)載于:https://www.cnblogs.com/Hammer-cwz-77/p/7337212.html
總結(jié)
以上是生活随笔為你收集整理的最短路和次短路问题,dijkstra算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓手机微信运动怎么不计步?
- 下一篇: oracle安装及卸载总结