hrbust 1040 Mining【SPFA+思维】

Mining
Time Limit: 2000 MSMemory Limit: 65536 K
Total Submit: 121(28 users)Total Accepted: 28(21 users)Rating: Special Judge: No
Description

Zfy and Kevin are friends and they like to go mining together at some place in the university. About at 6 p.m. they start to feel tired and want to go to dormitory. They want to get to dormitory quickly so each of them chooses a path that minimizes the distance to his dormitory. However, Zfy and Kevin also like to walk together in order that they can talk about the technique of mining,. So they want to walk together as much as possible.

 

The university which Zfy and Kevin study in can be modeled as a set of streets and junctions. Each street connects a pair of distinct junctions and can be walked in both directions. No two streets connect the same pair of junctions. Zfy and Kevin do not live together, and they do not live at the mine. There is at least one path from the mine to Zfy’s dormitory; the same occurs with Kevin’s dormitory.

 

Given information about the streets and junctions in the university, the locations of the mine, Zfy’s dormitory and Kevin’s dormitory, you must tell Zfy and Kevin the maximum distance that they can walk together without forcing them to walk more than the minimum distance from the mine to their respective dormitories. Zfy and Kevin also want to know how much each of them will walk alone.

Input

The first line contains an integer T, which is the number of test cases. The first line of each test case contains five integers J, B, C, N and S separated by single spaces. The value J is the number of junctions in the University (3 ≤ J ≤ 1000); each junction is identified by an integer number between 1 and J. The values B, C and N are the identifiers of the junctions where the mine, Zfy’s dormitory and Kevin’s are located, respectively (1 ≤ B, C, N ≤ J); these three junction numbers are different. The value S is the number of streets in the university (2 ≤ S ≤ 150000). Each of the next S lines contains the description of a street. Each street is described using three integers E1, E2 and L separated by single spaces, where E1 and E2 indicate two distinct junctions that are endpoints of the street (1 ≤ E1, E2 ≤ J), and L is the length of the street (1 ≤ L ≤ 104). You may assume that each street has a different pair of junctions, and that there always exist paths from junction B to junctions C and N.

Output

For each test case output a single line with three integers T, C and N separated by single spaces, where T is the maximum distance that Zfy and Kevin can walk together, C is the distance that Zfy walks alone, and N is the distance that Kevin walks alone.

Sample Input

2

5 3 2 1 6

3 4 10

4 5 10

5 1 3

5 2 4

1 3 23

2 3 24

8 1 7 8 8

1 2 1

2 4 1

2 3 1

4 5 1

3 5 1

5 6 1

6 8 1

6 7 1

Sample Output

20 4 3

4 1 1

Hint

The picture shows the map of the first test case. Zfy and Kevin walk together from 3 to 5, and then back to their dormitory respectively.


题目大意:

首先输入一个t,表示一共有t组数据,然后接下来一行五个元素,分别表示多少个点,起点,第一个人的终点,第二个人的终点,边的个数m,然后接下来m行,每行三个元素,表示a,b之间有一条路权值为c。问两个人在从起点到终点最短距离的情况下,从起点到终点共同走过的最长距离是多少。

对于输出三个数,第一个数表示两个人从起点到终点共同走过的最长距离是多少,第二个数表示第一个人要自己走多长的路,第三个数表示第二个人要自己走多长的路。


思路:


1、首先我们要有从起点s到t1,和t2的最短距离,然后我们枚举每一个点dis【i】,枚举从源点s到点i( 1<=i<=n)的路径,然后再加上从点i到点t1和点t2的距离,如果分别等于dis【t1】和dis【t2】那么说明从起点到点i的距离,就是一个两个人可以共同行走的一段距离,不过当然这个距离可能不是最大,那么我们在枚举的过程中,维护最大值即可。


2、对于从源点s到i的最短路径,我们求一遍以s为源点的最短路,对于从点i到t1的距离,我们以t1为源点求一遍最短路,同理,从点i到t2的距离,我们以t2为源点求一遍最短路。


3、按照刚才思路依次枚举,维护最大值即可。


4、注意的点:

①根据测试,题目保证有解。

②维护最大值的初始化maxn千万不要设为0,初始化要为-1,给出一组数据,这块是我的Wa点,不知道能否帮到大家:

2
5 3 3 1 6
3 4 10
4 5 10
5 1 3
5 2 4
1 3 23
2 3 24


Ac代码:


#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int head[100000];
struct EdgeNode
{
    int to;
    int w;
    int next;
}e[1500000];
int dis[4][100000];
int vis[100000];
int n,s,t1,t2,m,cont;
void add(int from,int to,int w)
{
    e[cont].to=to;
    e[cont].w=w;
    e[cont].next=head[from];
    head[from]=cont++;
}
void SPFA(int s,int d)
{
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)dis[d][i]=1999999999;
    dis[d][s]=0;
    vis[s]=1;
    queue<int >q;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();vis[u]=0;
        for(int i=head[u];i!=-1;i=e[i].next)
        {
            int v=e[i].to;
            int w=e[i].w;
            if(dis[d][v]>dis[d][u]+w)
            {
                dis[d][v]=dis[d][u]+w;
                if(vis[v]==0)
                {
                    q.push(v);
                    vis[v]=1;
                }
            }
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        cont=0;
        memset(head,-1,sizeof(head));
        scanf("%d%d%d%d%d",&n,&s,&t1,&t2,&m);
        for(int i=0;i<m;i++)
        {
            int x,y,w;
            scanf("%d%d%d",&x,&y,&w);
            add(x,y,w);
            add(y,x,w);
        }
        SPFA(s,0);
        SPFA(t1,1);
        SPFA(t2,2);
        int maxn=-1;
        int ans1=0;
        int ans2=0;
        for(int i=1;i<=n;i++)
        {
            if(dis[0][i]+dis[1][i]==dis[0][t1]&&dis[0][i]+dis[2][i]==dis[0][t2])
            {
                if(dis[0][i]>maxn)
                {
                    maxn=dis[0][i];
                    ans1=dis[1][i];
                    ans2=dis[2][i];
                }
            }
        }
        printf("%d %d %d\n",maxn,ans1,ans2);
    }
}
/*
2
5 3 3 1 6
3 4 10
4 5 10
5 1 3
5 2 4
1 3 23
2 3 24
*/




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值