zoukankan      html  css  js  c++  java
  • P4185 [USACO18JAN]MooTube

    这个题想了我2天,最后实在忍不住瞟了一眼题解,看到并查集三个字,一下就明白了。 还是利用离线 + 答案单调性的思想。不难发现,假如询问的$k$单调递减,那么答案一定单调递增。 所以考虑离线。将询问排序以后,每次将满足条件的边(即满足$k leq val$的边)连上,答案就是点所在连通块的大小。
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int MAXN = 1e5 + 20;
    inline int read()
    {
    	int x = 0; char ch = getchar(); bool f = false;
    	while(!isdigit(ch)) f |= (ch == '-'), ch = getchar();
    	while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
    	return f ? -x : x;
    }
    
    int N, Q;
    
    struct edge
    {
    	int from, to, cost;
    	inline bool operator <(const edge &rhs) const{
    		return cost > rhs.cost;
    	}
    };vector<edge> g;
    struct state
    {
    	int k, v, idx, res;
    }ask[MAXN];
    
    inline bool cmp1(state &lhs, state &rhs){
    	return lhs.k > rhs.k; 
    }
    inline bool cmp2(state &lhs, state &rhs){
    	return lhs.idx < rhs.idx;
    }
    
    namespace ufs
    {
    	int fa[MAXN], siz[MAXN];
    
    	void init(){for(int i = 1; i <= N; i++) fa[i] = i, siz[i] = 1;}
    	int findfa(int x){return fa[x] == x ? x : fa[x] = findfa(fa[x]);}
    	void unite(int x, int y){x = findfa(x), y = findfa(y), siz[y] += siz[x], fa[x] = y;}
    }
    
    int main()
    {
    	cin>>N>>Q;
    	for(int i = 1; i < N; i++){
    		int u = read(), v = read(), c = read();
    		g.push_back((edge){u, v, c});
    	}
    	for(int i = 1; i <= Q; i++){
    		int k = read(), v = read();
    		ask[i] = (state){k, v, i};
    	}
    
    	sort(ask + 1, ask + Q + 1, cmp1);
    	sort(g.begin(), g.end());
    
    	ufs::init(); vector<edge>::iterator it = g.begin();
    
    	for(int i = 1; i <= Q; i++){
    		while(it != g.end() && it->cost >= ask[i].k) ufs::unite(it->from, it->to), ++it;
    		ask[i].res = ufs::siz[ufs::findfa(ask[i].v)];
    	}
    	
    	sort(ask + 1, ask + Q + 1, cmp2);
    	for(int i = 1; i <= Q; i++) printf("%d
    ", ask[i].res - 1);
    	return 0;
    }
    
    
  • 相关阅读:
    java wait方法
    thread join
    AtomicReference 原理
    exchanger java另一种栅栏
    CyclicBarrier 栅栏 原理,应用场景
    信号量Semaphore
    FutureTask 解析
    CountDownLatch
    java 双端队列 Deque
    lockInterruptibly 和lock 原理
  • 原文地址:https://www.cnblogs.com/wsmrxc/p/9432848.html
Copyright © 2011-2022 走看看