标签:stream cell scan poj string 其他 span bsp ble
给出一张有n个点和m条双向边的图,要求求出1到n的次短路的长度。一条边可以多次通过。
输入格式:
第一行为两个整数n和m。接下来的m行每行三个整数ai,bi,vi,分别表示这条路连着的两个点和他的长度。
输出格式:
一个整数,表示次短路的长度。(次短路长度必须大于最短路,数据保证有解)
样例输入 |
样例输出 |
4 4 |
450 |
样例解释:
最短:1->2->4。
次短:1->2->3->4。
数据范围:
对于 100%的数据:1<=n、vi<=5000,1<=m<=100000。
首先更新的条件有两个:小于最短距离,大于最短距离且小于次短距离
如果新更新出的值小于最短路的值,那么把最短路的值变成新更新的值,次短路的值变成最短路的值
注意:要把现最短路的值和现次短路的值都进堆
如果新更新出的值大于最短距离且小于次短距离,那么仅更新次短路的值,且将次短路的值入堆
同样出堆的条件也应放宽到小于等于次短路径
注意:初始化时仅有S的最短路长度为0,其他都为inf(包括次短路长度)
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; int h[5100],to[200100],next[200100],k=0,cost[200100]; typedef pair<int,int> P; priority_queue<P,vector<P>,greater<P> > q; int dist[5100][2]; void ins(int u,int v,int w){next[++k]=h[u];h[u]=k;to[k]=v;cost[k]=w;} void dij(int S) { memset(dist,127/2,sizeof(dist)); dist[S][0]=0;q.push(P(0,S)); while(!q.empty()) { P p=q.top();q.pop();int u=p.second; if(dist[u][1]<p.first)continue; for(int i=h[u];i;i=next[i]) { int v=to[i]; if(p.first+cost[i]<dist[v][0]) { dist[v][1]=dist[v][0];dist[v][0]=p.first+cost[i]; q.push(P(dist[v][0],v));q.push(P(dist[v][1],v)); } else if(p.first+cost[i]<dist[v][1]&&p.first+cost[i]!=dist[v][0]) { dist[v][1]=p.first+cost[i]; q.push(P(dist[v][1],v)); } } } } int main() { freopen("short.in","r",stdin);freopen("short.out","w",stdout); int n,m;scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int x,y,z;scanf("%d%d%d",&x,&y,&z);ins(x,y,z);ins(y,x,z); } dij(1); printf("%d",dist[n][1]); return 0; }
标签:stream cell scan poj string 其他 span bsp ble
原文地址:http://www.cnblogs.com/lher/p/7594211.html