POJ 3255
2014-04-30 18:38
351 查看
思路:求次短路,先spfa,再枚举各条边,次短路一定是最短路换一条边得到。
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #define MAX 100005 #define INF 0xfffffff using namespace std; typedef struct{ int from, to, next, w; }Node; Node edge[2*MAX]; queue<int>q; int head[MAX], vis[MAX], dist[MAX], rdist[MAX]; void init(int n){ memset(head, -1, sizeof(head)); for(int i = 1;i <= n;i ++) dist[i] = rdist[i] = INF; dist[1] = rdist = 0; } void spfa(int s, int dist[]){ while(!q.empty()) q.pop(); memset(vis, 0, sizeof(vis)); q.push(s); vis[s] = 1; while(!q.empty()){ int p = q.front(); q.pop(); vis[p] = 0; for(int i = head[p];i != -1;i = edge[i].next){ int v = edge[i].to; if(dist[v] > dist[p] + edge[i].w){ dist[v] = dist[p] + edge[i].w; if(!vis[v]){ q.push(v); vis[v] = 1; } } } } } void AddEdge(int u, int v, int w, int i){ edge[i].from = u; edge[i].to = v; edge[i].w = w; edge[i].next = head[u]; head[u] = i; } int main(){ int R, N, u, v, w, secl; //freopen("in.c", "r", stdin); while(~scanf("%d%d", &N, &R)){ init(N); int i = 0; for(int j = 0;j < R;j ++){ scanf("%d%d%d", &u, &v, &w); AddEdge(u, v, w, ++i); AddEdge(v, u, w, ++i); } spfa(1, dist); spfa(N, rdist); secl = INF; for(int j = 1;j <= i;j ++){ u = edge[j].from; v = edge[j].to; if(dist[u] + edge[j].w + rdist[v] > dist && secl > dist[u] + edge[j].w + rdist[v]) secl = dist[u] + edge[j].w + rdist[v]; } printf("%d\n", secl); } return 0; }