• HDU 4912 Paths on the tree(LCA+贪心)


    题目链接 Paths on the tree

    来源  2014 多校联合训练第5场 Problem B

    题意就是给出m条树上的路径,让你求出可以同时选择的互不相交的路径最大数目。

    我们先求出每一条路径(u, v)中u和v的LCA:w,按照路径的w的深度大小deep[w]对所有的路径排序。

    deep[w]越大,排在越前面。

    然后从第一条路径开始一次处理,看c[u]和c[v]是否都没被标记过,如果都没被标记过则我们把这条路径选上,把答案加1。

    同时标记以w为根的子树的节点为1,方便后续对c数组的查询。

    时间复杂度$O(mlogn + mlogm + n)$

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    
    const int N = 1e5 + 10;
    const int A = 24;
    
    int f[N][A];
    int n, m, ans;
    int deep[N], c[N];
    vector <int> v[N];
    
    struct node{ 
    	int x, y, z;
    	friend bool operator < (const node &a, const node &b){
    		return deep[a.z] > deep[b.z];
    	}
    } p[N];
    
    void dfs(int x, int fa, int dep){
    	deep[x] = dep;
    	if (fa){ 
                    f[x][0] = fa;
    		for (int i = 0; f[f[x][i]][i]; ++i) f[x][i + 1] = f[f[x][i]][i];
    	}
    	for (auto u : v[x]){
    		if (u == fa) continue;
    		dfs(u, x, dep + 1);
    	}
    }
    
    int LCA(int a, int b){
    	if (deep[a] < deep[b]) swap(a, b);
    	for (int i = 0,  delta = deep[a] - deep[b]; delta; delta >>= 1, ++i) if (delta & 1) a = f[a][i];
    	if (a == b) return a;
    	dec(i, 19, 0) if (f[a][i] != f[b][i]) a = f[a][i], b = f[b][i];
    	return f[a][0];
    }
    
    void tag(int x){
    	c[x] = 1;
    	for (auto u : v[x]){
    		if (u == f[x][0]) continue;
    		if (c[u] == 0) tag(u);
    	}
    }
    
    int main(){
    
    
    	while (~scanf("%d%d", &n, &m)){
    		memset(f, 0, sizeof f);
    		rep(i, 0, n + 1) v[i].clear();
    		rep(i, 2, n){
    			int x, y;
    			scanf("%d%d", &x, &y);
    			v[x].push_back(y);
    			v[y].push_back(x);
    		}
    
    		memset(deep, 0, sizeof deep);
    		dfs(1, 0, 0);
    		ans = 0;
    
    		rep(i, 1, m){
    			int x, y;
    			scanf("%d%d", &x, &y);
    			int z = LCA(x, y);
    			p[i] = {x, y, z};
    		}
    
    		sort(p + 1, p + m + 1);
    
    		memset(c, 0, sizeof c);
    		rep(i, 1, m){
    			int u = p[i].x, w = p[i].y;
    			if (c[u] == 0 && c[w] == 0){
    				tag(p[i].z);
    				++ans;
    			}
    		}
    
    
    		printf("%d
    ", ans);
    
    
    	}
    	return 0;
    }
    
  • 相关阅读:
    cakephp引用CSS方法
    CakePHP Pagination (分頁功能) 加入自己的參數
    CakePHP 1.2 Model 資料驗証 (Data Validation) 簡介
    cakephp 配置
    CakePHP Pagination (分頁功能)
    CakePHP你必须知道的21条技巧
    CakePHP 1.2 Controller 簡介
    关于fckEditor的功能配置PHP版
    CakePHP 1.2 簡易安裝與設定
    CakePHP處理HTTP Request 典型的流程
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/7263978.html
Copyright © 2020-2023  润新知