• [动态图]


    给一个图,每一条边有一个消失的时刻,询问1~K每个时刻两两可达的点对有多少对?

    题目链接:http://poj.openjudge.cn/practice/C15C/

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    #define maxn 200010
    
    using namespace std;
    typedef long long ll;
    
    ll ans;
    int N, M, K;
    int h[maxn], cnt;
    struct Edge{int u, v, nxt;}edge[maxn];
    void add(int x, int u, int v){
    	edge[++ cnt] = (Edge){u, v, h[x]};
    	h[x] = cnt;
    }
    
    void init(){
    	memset(h, 0, sizeof h);
    	ans = cnt = 0;
    }
    
    struct Node{
    	int u, v, cntu, cntv, ranku, rankv;
    	Node(int u = 0, int v = 0, int cntu = 0, int cntv = 0, int ranku = 0, int rankv = 0):
    		u(u), v(v), cntu(cntu), cntv(cntv), ranku(ranku), rankv(rankv){}
    }st[maxn];
    
    int top;
    
    namespace Set{
    	int rank[maxn], fa[maxn], c[maxn];
    	
    	void Init(){
    		for(int i = 1; i <= N; i ++)
    		    c[i] = 1, fa[i] = i, rank[i] = 1;
    	}
    	
    	int Findroot(int x){
    		while(x != fa[x])x = fa[x];
    		return x;
    	}
    	
    	void Union(int u, int v){
            u = Findroot(u);
    		v = Findroot(v);
    		if(u == v)return;
    		ans += (ll)c[u] * c[v];
    		st[++ top] = (Node){u, v, c[u], c[v], rank[u], rank[v]};
            if(rank[u] == rank[v]){
    			if(c[u] < c[v])swap(u, v);
    			fa[v] = u;
    			c[u] += c[v];
    			rank[u] = rank[v] + 1;
    			return;
    		}
    		if(rank[u] < rank[v])swap(u, v);
    		fa[v] = u;
    		c[u] += c[v];
    	}
    	
    	int Pushback(int rtop){
    		for(; top > rtop; top --){
    			int u = st[top].u, v = st[top].v;
    			ans -= (ll)st[top].cntu * st[top].cntv;
    			fa[u] = u, fa[v] = v;
    			c[u] = st[top].cntu;
    			c[v] = st[top].cntv;
    			rank[u] = st[top].ranku;
    			rank[v] = st[top].rankv;
    		}
    	}
    }
    
    void cdq(int l, int r){
    	if(l == r){
    		printf("%lld
    ", ans);
    		return;
    	}
    	int mid = l + r >> 1, rtop = top;
    	for(int i = mid + 1; i <= r; i ++)
    	    for(int j = h[i]; j; j = edge[j].nxt)
    			Set::Union(edge[j].u, edge[j].v);
    	cdq(l, mid);
    	Set::Pushback(rtop);
    	for(int i = l; i <= mid; i ++)
    	    for(int j = h[i]; j; j = edge[j].nxt)
    	        Set::Union(edge[j].u, edge[j].v);
    	cdq(mid + 1, r);
    	Set::Pushback(rtop);
    }
    
    void solve(){
    	init();
    	int u, v, c;
    	Set::Init();
    	for(int i = 1; i <= M; i ++){
    		scanf("%d%d%d", &u, &v, &c);
    		add(c, u, v);
    	}
    	cdq(1, K);
    }
    
    int main(){
    	while(~scanf("%d%d%d", &N, &M, &K))
    	    solve();
    	return 0;
    }
    

      

    给时光以生命,而不是给生命以时光。
  • 相关阅读:
    k8s与监控--解读prometheus监控kubernetes的配置文件
    一天学习k8s
    Kubernetes入门:Pod、节点、容器和集群
    skywalking的核心概念
    skywalking的插件管理agent管理
    skywalking7 源码解析 (3) :agent启动服务分析以及性能影响
    HyperLedger Fabric 多机部署(一)
    Hyperledger Fabric 替换couchDB
    Hyperledger Fabric (1.0)环境部署 chaincode【转】
    Hyperledger Fabric 第一次安装
  • 原文地址:https://www.cnblogs.com/Candyouth/p/5553019.html
Copyright © 2020-2023  润新知