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

最短路

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 }
原文地址:https://www.cnblogs.com/cmyg/p/10063159.html