1. 程式人生 > >最短路 次短路 k短路(k很小)

最短路 次短路 k短路(k很小)

報錯 str != second 數據 iter back 推廣 name

最短路

luogu 3371

https://www.luogu.org/problemnew/show/P3371

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <queue>
 5 #include <algorithm>
 6 using namespace std;
 7 const int maxn=1e4+10;
 8 
 9 int dist[maxn];
10 bool vis[maxn];
11 
12 struct node
13 { 14 int d,len; 15 ///相反 16 bool operator<(const node & b) const 17 { 18 return b.len<len; ///b.d放在左邊,方便 19 } 20 }; 21 22 priority_queue<node> st;///這樣寫就可以了,省略後面的部分 23 vector<pair<int,int> >e[maxn]; 24 25 int main() 26 { 27 int n,m,s,x,y,z,d,i;
28 vector<pair<int,int> >::iterator j; 29 scanf("%d%d%d",&n,&m,&s); 30 for (i=1;i<=m;i++) 31 { 32 scanf("%d%d%d",&x,&y,&z); 33 //有向邊 34 e[x].push_back(make_pair(y,z)); 35 } 36 memset(dist,0x7f,sizeof(dist)); 37 dist[s]=0
; 38 st.push({s,0}); 39 ///點可以重復在priority_queue出現 40 while (1) 41 { 42 ///該點已被處理 43 ///若st為空,執行st.top()會報錯 44 while (!st.empty() && vis[st.top().d]) 45 st.pop(); 46 ///必不可少 47 if (st.empty()) 48 break; 49 ///以dist[d]為點d的最短路為基礎,進行拓展 50 d=st.top().d; 51 vis[d]=1;///! 52 st.pop();///! 53 for (j=e[d].begin();j!=e[d].end();j++) 54 if (dist[j->first]>dist[d]+j->second) 55 { 56 dist[j->first]=dist[d]+j->second; 57 st.push({j->first,dist[j->first]}); 58 } 59 } 60 for (i=1;i<=n;i++) 61 { 62 if (i!=1) 63 printf(" "); 64 printf("%d",dist[i]==dist[0]?2147483647:dist[i]); 65 } 66 return 0; 67 }

次短路

poj3255

http://poj.org/problem?id=3255

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <queue>
 5 #include <algorithm>
 6 using namespace std;
 7 const int maxn=5e3+10;
 8 int ci=2;
 9 
10 ///次短路,可以推廣位k短路(當然k要較小),此時dist的第二維的大小需要增加,第二維的數據修改也要修改
11 
12 struct node
13 {
14     int d,len;
15     node *next;
16 }*e[maxn];
17 
18 struct rec
19 {
20     int d,dist;
21     bool operator<(const rec &b) const
22     {
23         return b.dist<dist;
24     }
25 };
26 priority_queue<rec> st;
27 
28 int hap[maxn],dist[maxn][3];
29 
30 int main()
31 {
32     int i,a,b,c,n,m,d,dis,dd,ddis;
33     node *p;
34     scanf("%d%d",&n,&m);
35     for (i=1;i<=m;i++)
36     {
37         scanf("%d%d%d",&a,&b,&c);
38         p=new node();
39         p->d=b;
40         p->len=c;
41         p->next=e[a];
42         e[a]=p;
43 
44         p=new node();
45         p->d=a;
46         p->len=c;
47         p->next=e[b];
48         e[b]=p;
49     }
50 
51     ///from 1 to n
52     memset(dist,0x7f,sizeof(dist));
53     dist[1][1]=0;
54     st.push({1,0});
55     while (1)
56     {
57         while (!st.empty() && hap[st.top().d]==ci)
58             st.pop();
59         ///if not exists(not break in the next period)
60         if (st.empty())
61             break;
62 
63         ///確定了d,dist是第hap[d]小,以此為基礎拓展其它點的第一小和第二小
64         d=st.top().d;
65         dis=st.top().dist;
66         hap[d]++;
67         st.pop();
68 
69         if (d==n && hap[d]==2)
70             break;
71 
72         p=e[d];
73         while (p)
74         {
75             dd=p->d;
76             ddis=dis+p->len;
77             if (ddis<dist[dd][1])
78             {
79                 dist[dd][2]=dist[dd][1];
80                 dist[dd][1]=ddis;
81                 st.push({dd,ddis});///{d,dis[dd][1]}已經在優先隊列裏了
82             }
83             else if (ddis<dist[dd][2])
84             {
85                 dist[dd][2]=ddis;
86                 st.push({dd,ddis});
87             }
88             p=p->next;
89         }
90     }
91     ///if not exists
92     printf("%d",dist[n][2]);
93     return 0;
94 }

最短路 次短路 k短路(k很小)