poj 3255 spfa(求次短路)

来源:互联网 发布:网络推广框架协议 编辑:程序博客网 时间:2024/05/16 15:38

题意:给定一个带权无向图,顶点标号为1~n。求从点1到点n之间的次短路长度。

思路:首先分别求出起点和终点到图中每个点的最短路,分别记录在dis1[N]和disn[N]这两个数组中(显然起点到终点的最短路就是dis1[n]或者disn[1])。此后枚举每一条边e,对其两个端点u,v,求大于dis1[n]的 “dis1[u] + e的长度 + disn[v]” 值的最小值。(但是如何证明?)

#include <stdio.h>#include <string.h>#define min(a,b) ((a)<(b)?(a):(b))#define N 5005#define INF 0x3fffffffstruct edge{int y,w,next;}e[100005<<1];int first[N],dis1[N],disn[N],used[N],q[1000000];int n,m,top;void add(int x,int y,int w){e[top].y = y;e[top].w = w;e[top].next = first[x];first[x] = top++;}int relax(int x,int y,int w,int dis[N]){if(dis[x]+w < dis[y]){dis[y] = dis[x] + w;return 1;}return 0;}void spfa(int s,int dis[N]){int i,front,rear,now;memset(used,0,sizeof(used));for(i = 1;i<=n;i++)dis[i] = INF;dis[s] = 0;front = rear = -1;q[++rear] = s;while(front < rear){now = q[++front];used[now] = 0;for(i = first[now];i!=-1;i=e[i].next)if(relax(now,e[i].y,e[i].w,dis) && !used[e[i].y]){used[e[i].y] = 1;q[++rear] = e[i].y;}}}int main(){freopen("a.txt","r",stdin);while(scanf("%d %d",&n,&m)!=EOF){int a,b,w,i,j,res;memset(first,-1,sizeof(first));top = 0;res = INF;for(i = 0;i<m;i++){scanf("%d %d %d",&a,&b,&w);add(a,b,w);add(b,a,w);}spfa(1,dis1);spfa(n,disn);for(i = 1;i<=n;i++)for(j = first[i];j!=-1;j=e[j].next)if(dis1[i]+disn[e[j].y]+e[j].w > dis1[n])res = min(res,dis1[i]+disn[e[j].y]+e[j].w);printf("%d\n",res);}return 0;}


0 0
原创粉丝点击