/*****************************************
Author :Crazy_AC(JamesQi)
Time :
File Name :
思路:分别以源点1和终点N为源点,两次SPFA求得dist1[i](1到各点的最短距离)以及dist2[i](各点到N的最短距离),
然后就是枚举边了,设某一条边的两端为u,v,权值为w,则dist1[u]+w+dist2[v]即为1->N的一条路径,在所有的路径中
找出次短的即可。
*****************************************/
#include <iostream>
#include <algorithm>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
using namespace std;
#define FILL(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a)
template<class T> inline T Get_Max(const T&a,const T&b) {return a < b?b:a;}
template<class T> inline T Get_Min(const T&a,const T&b) {return a < b?a:b;}
const int inf = 1 << 30;
const int maxn = 5000;
struct Edge{
int to,w;
Edge(){}
Edge(int to,int w):to(to),w(w){}
};
int dis1[maxn],dis2[maxn];
int mark[maxn];
int n,m;
vector<vector<Edge> > G;
void spfa(int st,int dist[])
{
memset(mark,0,(n + 2)*sizeof(int));
fill(dist,dist + n + 2,inf);
dist[st] = 0;
queue<int> que;
que.push(st);
mark[st] = 1;
while(!que.empty())
{
int u = que.front();
mark[u] = 0;
que.pop();
for (int i = 0;i < G[u].size();i++)
{
int v = G[u][i].to;
int w = G[u][i].w;
if (dist[v] > dist[u] + w)
{
dist[v] = dist[u] + w;
if (!mark[v])
{
mark[v] = 1;
que.push(v);
}
}
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d%d",&n,&m) != EOF)
{
G.clear();
G.resize(n + 2);
int u,v,w;
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
G[u].push_back(Edge(v,w));
G[v].push_back(Edge(u,w));
}
spfa(1,dis1);
spfa(n,dis2);
int ans1 = inf,ans2 = inf;
for (int u = 1;u <= n;u++)
{
for (int i = 0;i < G[u].size();i++)
{
int v = G[u][i].to;
int w = G[u][i].w;
if (dis1[u] + dis2[v] + w < ans1)
{
ans2 = ans1;
ans1 = dis1[u] + dis2[v] + w;
}
else if (dis1[u] + dis2[v] + w < ans2 && dis1[u] + dis2[v] + w != ans1)
{
ans2 = dis1[u] + dis2[v] + w;
}
}
}
printf("%d\n",ans2);
}
return 0;
}
poj3255基础次短路
最新推荐文章于 2022-03-09 16:55:41 发布