(BAPC 2014 Preliminary) B. Failing Components(最短路径问题)

 

 

  •  1500ms
  •  262144K

 

 

As a jury member of the Best Architectural Planning Contest, you are tasked with scoring the reliability of a system. All systems entered in the contest consist of a number of components which depend on each other. The reliability of such a system depends on the damage done by a failing component. Ideally a failing component should have no consequences, but since most components depend on each other, some other components will usually fail as well.

Most components are somewhat resilient to short failures of the components they depend on. For example, a database could be unavailable for a minute before the caches expire and new data must be retrieved from the database. In this case, the caches can survive for a minute after a database failure, before failing themselves. If a component depends on multiple other components which fail, it will fail as soon as it can no longer survive the failure of at least one of the components it depends on. Furthermore no component depends on itself directly, however indirect self-dependency through other components is possible.

You want to know how many components will fail when a certain component fails, and how much time passes before all components that will eventually fail, actually fail. This is difficult to calculate by hand, so you decided to write a program to help you. Given the description of the system, and the initial component that fails, the program should report how many components will fail in total, and how much time passes before all those components have actually failed.

Input Format

On the first line one positive number: the number of test cases, at most 100. After that per test case:

  • one line with three space-separated integers nn, dd and cc (1\leq n \leq 100001≤n≤10000 and 1 \leq d \leq 1000001≤d≤100000 and 1 \leq c \leq n1≤cn): the total number of components in the system, the number of dependencies between components, and the initial component that fails, respectively.

  • dd lines with three space-separated integers aa, bb and ss (1 \leq a,b \leq n1≤a,bn and a\ != ba !=b and 0 \leq s \leq 1 0000≤s≤1000), indicating that component aa depends on component bb, and can survive for ss seconds when component bb fails.

In each test case, all dependencies (a, b)(a,b) are unique.

Output Format

Per test case:

  • one line with two space-separated integers: the total number of components that will fail, and the number of seconds before all components that will fail, have actually failed.

样例输入

2
3 2 2
2 1 5
3 2 5
3 3 1
2 1 2
3 1 8
3 2 4

样例输出

2 5
3 6

题目来源

BAPC 2014 Preliminary

#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 10010
using namespace std;
typedef pair<int, int> Pair;
struct Node
{
    int to;
    int w;
};
vector<Node> vs[MAXN];              //这个实际上就是用c++ 写的化简版邻接表
int dis[MAXN];
void bfs(int s)                     //注:这个图是有向图,满足拓扑排序原则,
{                                   //所以有先后顺序的实际问题,考虑要素:1.有向无向。2.是否是拓扑排序
    int i;
    priority_queue<Pair,vector<Pair>,greater<Pair> > si;
    dis[s]=0;
    si.push(Pair(0,s));             // first是从起点到second点的最短距离
    while(!si.empty())             //c++版 邻接表的广搜。
    {
        Pair p;
        p=si.top();
        si.pop();
        if(dis[p.second]<p.first)               
        continue;                              //这个判断成立,就不可能用这个点算转达,所以直接结束
        for(i=0;i<vs[p.second].size();i++)     //找最短距离,
        {
            Node e=vs[p.second][i];
            if(dis[e.to]>dis[p.second]+e.w)
            {
                dis[e.to]=dis[p.second]+e.w;
                si.push(Pair(dis[e.to], e.to));//利用广搜来找最短路径
            }
        }
    }
    return;
}
int main()
{
    int t, n, d, c;
    int i;
    scanf("%d", &t);
    while(t--)
    {
        for(i=1;i<=MAXN-1;i++)
        dis[i]=INF;
        scanf("%d%d%d",&n,&d,&c);
        for(i=1;i<=d;i++)
        {
            int a,b,s;
            Node e;
            scanf("%d%d%d", &a, &b, &s);   //被依赖方是弧尾
            e.to=a,e.w=s;
            vs[b].push_back(e);
        }
        bfs(c);
        int cnt=0,MIN=0;
        for(i=1;i<=n;i++)
        {
            if(dis[i]!=INF)
            {
                cnt++;
                MIN=max(MIN, dis[i]);   //最后这里是算最长的,因为要算所有点
            }
        }
        for(i=1;i<=n;i++)
        {
            vs[i].clear();
        }
        printf("%d %d\n",cnt,MIN);
    }
    return 0;
}

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值