hrbust 1050 Hot Pursuit II【SPFA+次短路】

Hot Pursuit II
Time Limit: 1000 MSMemory Limit: 65536 K
Total Submit: 44(15 users)Total Accepted: 20(11 users)Rating: Special Judge: No
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.
Hot Pursuit II is a story of racers and police. The racers have great cars and always race on the street. The police hide nearly everywhere to pursuit these mad drivers. They sometimes use helicopters, roadblocks and heavy SUV cars. So the police is a big headache of racing. If followed by several police cars, you hardly can win the race.
Hot Pursuit II is based on an open map, which means there're several different ways leading to the finishing line. You can choose whichever you like. Liuctic is quite familiar of the map. He has driven on them nearly a thousand times, he can easily tell which road is the shortest. But he found that the shortest road hides more police than the others. He wants to win the race, so the shortest road is not always the best choice. Though the second shortest road may share a few paths with the shortest one, it reduces the probability of police's appearance. Then he decides to drive on the second shortest road. His experience can not tell which road is the second shortest, so he needs some calculation. He cracked the data file and found the maps is stored in the following format:
m
N1 a11 v11 a12 v12 a13 v13...
N2 a21 v21 a22 v22 a23 v23 ...
...
Nm am1 vm1 am2 vm2 am3 vm3 ...
It begins with an integer m, the number of places. Then m lines followed. The i-th line describes the i-th place. Ni is the number of adjacent places of the i-th place, followed by Ni pairs of positive integers. Each pair is made up of an index of a place, and the distance(<10000) from the i-th place to itself. The roads are all uni-directional and the indices of the pairs are different(for example, if the i-th place and the j-th place ARE ADJACENT, there is at most one road from i to j, and at most one road from j to i). The index starts from 1. m<1000, Ni<100.

Input

There're several maps.
The input data ensures that there are more than 1 path from place 1 to place m. Input ends with EOF. Suppose the shortest length is S, if there're more than one path with the length S, we can say S is also the second shortest length.

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
2 2 1 3 1
1 3 2
1 1 2
3
2 2 1 3 1
1 3 2
1 1 2

Sample Output

3
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);
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值