POJ-3255-Roadblocks(次短路)

POJ-3255-Roadblocks(次短路)

Bessie has moved to a small farm and sometimes enjoys returning to visit one of her best friends. She does not want to get to her old home too quickly, because she likes the scenery along the way. She has decided to take the second-shortest rather than the shortest path. She knows there must be some second-shortest path.

The countryside consists of R (1 ≤ R ≤ 100,000) bidirectional roads, each linking two of the N (1 ≤ N ≤ 5000) intersections, conveniently numbered 1…N. Bessie starts at intersection 1, and her friend (the destination) is at intersection N.

The second-shortest path may share roads with any of the shortest paths, and it may backtrack i.e., use the same road or intersection more than once. The second-shortest path is the shortest path whose length is longer than the shortest path(s) (i.e., if two or more shortest paths exist, the second-shortest path is the one whose length is longer than those but no longer than any other path).

Input
Line 1: Two space-separated integers: N and R
Lines 2… R+1: Each line contains three space-separated integers: A, B, and D that describe a road that connects intersections A and B and has length D (1 ≤ D ≤ 5000)
Output
Line 1: The length of the second shortest path between node 1 and node N
Sample Input
4 4
1 2 100
2 4 200
2 3 250
3 4 100
Sample Output
450
Hint
Two routes: 1 -> 2 -> 4 (length 100+200=300) and 1 -> 2 -> 3 -> 4 (length 100+250+100=450)

题目大意:

给你一个无向带权图,求1到n 的次短路(第二短的路)。

解题思路

我们求两遍最短路,一遍以1为起始点跑一遍最短路,然后把结果存在dis[]数组中,然后我们在以n为起点跑一遍最短路,结果存在dis2[]数组里。

然后我们遍历图得每一条边,假设当前边是 (u,v)权值是w,然后我们我们判断一下 dis[u]——1到u的距离+dis2[v]——v到n的距离 +w是否等于最短路 dis[n],如果等于那就说明这条是最短路,直接跳过就行,如果不等于,那就看他能否更新 ans(次短路的值)

AC代码:


#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <string>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=5500;
int head[maxn];
int dis[maxn];
int dis2[maxn];
int vis[maxn];
int path[maxn];
int cnt=0;
int n,m;
struct nod{
	int to;
	int val;
	int next;
}side[maxn*maxn];
struct Node{
	int to;
	int val;
	Node(){}
	Node(int t,int v):to(t),val(v){}
	
	friend bool operator <(Node a,Node b)
	{
		return a.val>b.val;
	}
};

void init()
{
	memset(path,-1,sizeof(path));
	memset(vis,0,sizeof(vis));
	memset(head,-1,sizeof(head));
	memset(dis,inf,sizeof(dis));
	memset(dis2,inf,sizeof(dis2));
	cnt=0;
}
void add(int x,int y,int w)
{
	side[cnt].to=y;
	side[cnt].val=w;
	side[cnt].next=head[x];
	head[x]=cnt++;
}
void Dijkstra1(int s,int e)
{
	memset(vis,0,sizeof(vis));
	priority_queue<Node> q;
	q.push(Node(s,0));
	dis[s]=0;
	while(q.size())
	{
		Node now=q.top();
		q.pop();
		if(vis[now.to])
			continue;
		vis[now.to]=1;
		for(int i=head[now.to];i!=-1;i=side[i].next)
		{
			int tmp=side[i].to;
			if(dis[tmp]>dis[now.to]+side[i].val)
			{
				dis[tmp]=dis[now.to]+side[i].val;
				q.push(Node(tmp,dis[tmp]));
			}
		}
	}
	return ;
}
void Dijkstra2(int s,int e)
{
	memset(vis,0,sizeof(vis));
	priority_queue<Node> q;
	q.push(Node(s,0));
	dis2[s]=0;
	while(q.size())
	{
		Node now=q.top();
		q.pop();
		if(vis[now.to])
			continue;
		vis[now.to]=1;
		for(int i=head[now.to];i!=-1;i=side[i].next)
		{
			int tmp=side[i].to;
			if(dis2[tmp]>dis2[now.to]+side[i].val)
			{
				dis2[tmp]=dis2[now.to]+side[i].val;
				q.push(Node(tmp,dis2[tmp]));
			}
		}
	}
	return ;
}

 int main()
 {
 	cin>>n>>m;
 	init();
 	while(m--)
 	{
 		int a,b,w;
 		cin>>a>>b>>w;
 		add(a,b,w);
 		add(b,a,w);
 	}
 	Dijkstra1(1,n);
 	Dijkstra2(n,1);
 	int min_rode=dis[n];
 	int ans=inf;
 	for(int i=1;i<=n;i++)
 	{
 		for(int j=head[i];j!=-1;j=side[j].next)
 		{
 			int tmp=side[j].to;
 			if(dis[i]+dis2[tmp]+side[j].val==min_rode)
 				continue;
 			else
 			{
 				ans=min(ans,dis[i]+dis2[tmp]+side[j].val);
			 }
		 }
	 }
	 cout<<ans<<endl;
	 return 0;


 }

猜你喜欢

转载自blog.csdn.net/weixin_43179892/article/details/85110237