Hot Pursuit II | ||||||
| ||||||
Description | ||||||
Liuctic is a great fan of Need For Speed, the most popular racing game on PC platform. He has played from NFS 3 to NFS 12 in the past 8 years. However, his favourate is NFS 6, named Hot Pursuit II. | ||||||
Input | ||||||
There're several maps. | ||||||
Output | ||||||
For each map,output the length of the second shortest road from place 1 to place m in a single line. | ||||||
Sample Input | ||||||
3 | ||||||
Sample Output | ||||||
3 |
题目大意:给你n个点,对应给出一个有向图,在保证有解的情况下,求出从1到n的次短路。
思路:
1、对于一条边,s-e,那么求一条从1到n的次短路,其实就是相当于求:从1到s的最短路+从e到n的最短路+s-e的边权值。
2、对于一个有向图,求从1到s的最短路,就是求一遍以1作为源点的最短路,从e到n的最短路,相当于求一遍以n作为源点的最短路,这里当然要反向见图,然后暴力枚举即可。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<vector>
#include<queue>
using namespace std;
struct node
{
int v,w;
}now,nex;
int n;
int vis[5000];
int dis[5000];
int dis2[5000];
vector<node >mp[5000];
vector<node >mp2[5000];
void SPFA(int ss)
{
queue<int >s;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)dis[i]=0x3f3f3f3f;
dis[ss]=0;vis[ss]=1;
s.push(ss);
while(!s.empty())
{
int u=s.front();
s.pop();vis[u]=0;
for(int i=0;i<mp[u].size();i++)
{
now=mp[u][i];
int v=now.v;
int w=now.w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(vis[v]==0)
{
vis[v]=1;
s.push(v);
}
}
}
}
}
void SPFA2(int ss)
{
queue<int >s;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)dis2[i]=0x3f3f3f3f;
dis2[ss]=0;vis[ss]=1;
s.push(ss);
while(!s.empty())
{
int u=s.front();
s.pop();vis[u]=0;
for(int i=0;i<mp2[u].size();i++)
{
now=mp2[u][i];
int v=now.v;
int w=now.w;
if(dis2[v]>dis2[u]+w)
{
dis2[v]=dis2[u]+w;
if(vis[v]==0)
{
vis[v]=1;
s.push(v);
}
}
}
}
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)mp[i].clear(),mp2[i].clear();
for(int i=1;i<=n;i++)
{
int k;
scanf("%d",&k);
for(int j=0;j<k;j++)
{
int v,w;
scanf("%d%d",&v,&w);
now.v=v;
now.w=w;
mp[i].push_back(now);
now.v=i;
now.w=w;
mp2[v].push_back(now);
}
}
SPFA(1);
SPFA2(n);
int minn,ciminn;
minn=ciminn=0x3f3f3f3f;
for(int i=1;i<=n;i++)
{
for(int j=0;j<mp[i].size();j++)
{
now=mp[i][j];
int u=i;
int v=now.v;
int w=now.w;
int tmp;
int ww=w+dis[u]+dis2[v];
if(ww<minn)
{
tmp=minn;
minn=ww;
ww=tmp;
}
if(ww<ciminn&&ww!=minn)
{
ciminn=min(ciminn,ww);
}
}
}
printf("%d\n",ciminn);
}
}