最小生成树应用解(超时)蓝桥杯2015初赛]灾后重建

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <set>Party smileBe right back
  4 using namespace std;
  5 constexpr size_t maxn = 2e5+1;
  6 int n, m, q;
  7 struct Edge{
  8 	int from, to, cost;
  9 	Edge(int from, int to, int cost){
 10 		this->from = from;
 11 		this->to = to;
 12 		this->cost = cost;
 13 	}
 14 };
 15 void easy(int,int,int,int);
 16 
 17 struct UFNode{
 18 	UFNode* parent;
 19 	UFNode():parent(NULL){}
 20 };
 21 
 22 bool cmp(Edge* e1, Edge* e2){
 23 	return e1->cost < e2->cost;
 24 }
 25 Edge* edges[maxn];
 26 UFNode* find(UFNode* p){
 27 	if(p->parent == NULL)return p;
 28 	set<UFNode*> path;
 29 	while(p->parent != NULL){
 30 		path.insert(p);
 31 		p = p->parent;
 32 	}
 33 	auto iter = path.begin();
 34 	while(iter != path.end()){
 35 		(*iter)->parent = p;
 36 		iter++;
 37 	}
 38 	return p;
 39 }
 40 void merge(UFNode* p1, UFNode* p2){
 41 	find(p2)->parent = find(p1);
 42 }
 43 UFNode point[50001];
 44 
 45 int main(){
 46 
 47 	cin >> n >> m >> q;
 48 	for(int i = 0; i < m; ++ i){
 49 		int a, b, c;
 50 		cin >> a >> b >> c;
 51 		Edge* e = new Edge(a, b, c);
 52 		edges[i] = e;
 53 	}
 54 	//排序 
 55 	sort(edges, edges + m, cmp);
 56 	for(int i = 0; i < q; ++ i){
 57 		int l, r, mod, c;
 58 		cin >> l >> r >> mod >> c;
 59 		easy(l, r, mod, c);
 60 	}
 61 	return 0;
 62 }
 63 
 64 
 65 void easy(int l, int r, int mod, int c){
 66 	for(int j = 0; j <= n; ++ j){
 67 		point[j].parent = NULL;
 68 	}
 69 	for(int i = 0; i < m; ++ i){
 70 		Edge* pEdge = edges[i];
 71 		int from = pEdge->from;
 72 		int to = pEdge->to;
 73 		int cost = pEdge->cost;
 74 
 75 		if(find(&point[from]) == find(&point[to]))//已经在一颗树上
 76 			continue;
 77 		else
 78 			merge(&point[from], &point[to]);
 79 		//if n-1 者最小生成数已经完成
 80 		UFNode* parent = NULL;
 81 		bool isok = true;
 82 		for(int j = l; j <= r; ++ j){
 83 			if(j%mod == c){
 84 				if(parent == NULL){
 85 					parent = find(&point[j]);
 86 				}
 87 				else{
 88 					if(parent != find(&point[j])){
 89 						isok = false;
 90 						break;
 91 					}
 92 				}
 93 			}
 94 		}
 95 		if(isok){
 96 			cout << cost << endl;
 97 			break;
 98 		}
 99 	}
100 }
posted @ 2020-02-27 20:03  ACWink  阅读(506)  评论(0编辑  收藏  举报