最短路 次短路 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 }