【BAPC 2014 Preliminary 】 B. Failing Components

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 nndd and cc (1\leq n \leq 100001n10000 and 1 \leq d \leq 1000001d100000 and 1 \leq c \leq n1cn): 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 aabb and ss (1 \leq a,b \leq n1a,bn and a\ != ba !=b and 0 \leq s \leq 1 0000s1000), indicating that component aa depends on component bb, and can survive for ss seconds when component bbfails.

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

图论的题目,大概意思是说:是说一些组件之间的关系的,先给出t,t组数据,每组数据先给出n表示组件总数,d表示依赖关系组数,c表示最开始失效的组件编号,然后d行,每行a,b,s;a依赖于b(也就是b失效了a也会失效),s是在b失效后随之a失效这两个组件失效间隔的时间。最后要输出的就是,c组件失效后总共会有多少个组件失效,以及所有失效组件都失效所花费的时间总数。

自己一开始的代码,通过find函数从第一个失效组件开始递归,可以实现找到失效组件的总个数:

for(int i = 0; i < d; i++) {
  scanf("%d%d%d", &a, &b, &s);
  v[b].push_back(a);//b失效后a也会失效,把b所能导致失效的组件放到vector数组b里面 
}
int find(int p) {
  if(vis[p] == 1) return 0;//vis数组标记该组件是否已经失效 
  else {
    vis[p] = 1;
    int temp = 1;
    for(int i = 0; i < v[p].size(); i++) {
      if(vis[v[p][i]] == 0) temp += find(v[p][i]);
    }
    return temp;
  }
}

正确做法(防止爆内存,开两个动态数组容器来存):

#include<iostream>
#include<set>
#include<vector>
using namespace std;
const int N = 100000+3;
struct Component {
	void reset(int id_) { 
    id = id_; 
    q.clear(); 
    s.clear(); 
    failed = false;
  }
	int id;
	vector<int> q;//存点 
	vector<int> s;//存时间 
	bool failed;
}comps[N];
struct Event {
	Event(int t, int c) {
    time = t; 
    comp = c;
  }
	int time;
	int comp;	
	bool operator< (const Event& b) const {
		if (time != b.time) return time < b.time;
		return comp < b.comp;	
	}
};
int main() {
	int t; 
  cin >> t;
	while(t--){
		int n, d, c; 
    cin >> n >> d >> c;
		for(int i = 1; i <= n; i++) 
      comps[i].reset(i);
		for(int i = 1; i <= d; i++) {
			int a, b, s; 
      cin >> a >> b >> s;
			comps[b].q.push_back(a);//以后端点存入 
			comps[b].s.push_back(s);			
		}
		set<Event> H;
		int t = 0;
		H.insert(Event(t, c));
		//如果某一组件失效了,会导致多个组件失效,先算时间小的 
		while(!H.empty()) {
			c = H.begin()->comp;
			//cout << "当前的点为: " << c << endl;
			int new_t = H.begin()->time; 
			H.erase(H.begin());
			if(comps[c].failed)	continue;		
			t = new_t;
			//cout << "当前花费的时间为: " << t << endl;
			comps[c].failed = true;		
			for ( int i = 0; i < comps[c].q.size(); i++ ) {
				int c2 = comps[c].q[i];
				if(!comps[c2].failed) {
				  H.insert(Event(t+comps[c].s[i], c2));//插入到set的时候,EvEnt结构体会对时间进行排序 
				  //cout << "加入点" << c2 << " 新加入该点c2与前驱点c之间花费的时间:" << comps[c].s[i] << endl;
				}
			}
		}
		int sum = 0;
		for(int i = 1; i <= n; i++) 
      if (comps[i].failed) sum++;
		cout << sum << " " << t << endl;
	}
	return 0;	
}
/*
4
4 3 1
4 1 8
2 1 2
3 2 7
*/ 

迪杰斯特拉解法:

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int nmax = 100000, dmax = 1000000;
const int infty = 1<<30;
vector<int> Adj[nmax], Len[nmax];
int Dis[nmax];
struct node {	
  int k, dis;
	node (int a, int b): k(a), dis(b) {}
};
bool operator < (const node &a, const node &b) {	
  return a.dis > b.dis;
}
void dijkstra (int start, int n) {	
  int i, j, k, dis;
	priority_queue<node> pq;
	for (i = 0; i < n; i++)
		Dis[i] = infty;
	Dis[start] = 0;
	pq.push(node(start, 0));
	while (!pq.empty())
	{	k = pq.top().k;
		dis = pq.top().dis;
		pq.pop();
		if (Dis[k] < dis)
			continue;
		for (i = Adj[k].size()-1; i >= 0; i--)
			if (Dis[j = Adj[k][i]] > dis + Len[k][i])
				pq.push(node(j, Dis[j] = dis + Len[k][i]));
	}
}
int main() {	
  int t, n, d, c, a, b, s, i, m, t;
	scanf("%d", &t);
	while(t--) {
		scanf("%d %d %d", &n, &d, &c);
		for (i = 0; i < n; i++) {
    	Adj[i].clear();
			Len[i].clear();
		}
		for (i = 0; i < d; i++) {
    	scanf("%d %d %d", &a, &b, &s);
			Adj[b-1].push_back(a-1);
			Len[b-1].push_back(s);
		}

		dijkstra(c-1, n); // Shortest path algorithm
		// Find failed components
		m = 0;
		t = 0;
		for (i = 0; i < n; i++)
			if (Dis[i] < infty) {
      	m++;
				t = max(t, Dis[i]);
			}
		printf("%d %d\n", m, t);
	}
	return 0;
}




猜你喜欢

转载自blog.csdn.net/daixinliangwyx/article/details/81006848