zoukankan      html  css  js  c++  java
  • hdu 4912

    Paths on the tree
    Problem Description
    bobo has a tree, whose vertices are conveniently labeled by 1,2,…,n.**

    There are m paths on the tree. bobo would like to pick some paths while any two paths do not share common vertices.**

    Find the maximum number of paths bobo can pick.**

    Input
    The input consists of several tests. For each tests:**

    The first line contains n,m (1≤n,m≤105). Each of the following (n - 1) lines contain 2 integers ai,bi denoting an edge between vertices ai and bi (1≤ai,bi≤n). Each of the following m lines contain 2 integers ui,vi denoting a path between vertices ui and vi (1≤ui,vi≤n).**

    Output
    For each tests:

    A single integer, the maximum number of paths.**

    Sample Input
    3 2
    1 2
    1 3
    1 2
    1 3
    7 3
    1 2
    1 3
    2 4
    2 5
    3 6
    3 7
    2 3
    4 5
    6 7

    Sample Output
    1
    2

    析:n个点的树中有两个点构成的m条路,求每一条路都不包含公共点或边的情况下最多的路的条数,用LCA倍增算法,求出每条路的两个点的LCA,并对其LCA按深度从大到小排序,先取深度较大的边,这样并不会对浅边产生影响,但要维护其LCA下的所有子节点,对其进行标记,避免重复

    #include <vector>
    #include <queue>
    #include <math.h>
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define ull unsigned ll
    #define Inf 0x7fffffff
    #define maxn 100005
    #define maxm 100005
    #define P pair<int, int>
    using namespace std;
    const int N = 300005;
    int t, n, m, len, ans;
    int vis[maxn], deep[maxn];
    int x, y, mark[maxn], f[maxn][30];
    vector<int>V[maxn];
    struct Node{
        int x, y, p;
        bool operator<(const Node &a)const{
            return deep[p] > deep[a.p];
        }
    }g[maxn];
    void init(){
        for(int i = 1; i <= n; i ++){
            vis[i] = deep[i] = mark[i] = 0;
            fill(f[i], f[i]+30, 0);
            V[i].clear();
        }
    }
    void dfs(int u){
        vis[u] = 0;
        for(int i = 0; i < V[u].size(); i ++){
            int v = V[u][i];
            if(f[u][0] == v)
                continue;
            if(!vis[v]){
                deep[v] = deep[u]+1;
                f[v][0] = u;
                dfs(v);
            }
        }
    }
    void cal(){
        for(int i = 1; (1<<i) <= n; i ++){
            for(int j = 1; j <= n; j ++){
                f[j][i] = f[f[j][i-1]][i-1];
            }
        }
    }
    int LCA(int x, int y){
        if(deep[x] < deep[y])
            swap(x, y);
        int j, i = 0;
        while((1<<(i+1)) <= deep[x])
            i ++;
        for(j = i; j+1; j --){
            if(deep[x]-(1<<j) >= deep[y]){
                x = f[x][j];
            }
        }
        if(x == y) return x;
        for(j = i; j+1; j --){
            if(f[x][j] != f[y][j]){
                x = f[x][j];
                y = f[y][j];
            }
        }
        return f[x][0];
    }
    void solve(int u){
        mark[u] = 1;
        for(int i = 0; i < V[u].size(); i ++){
            int v = V[u][i];
            if(deep[u]+1 == deep[v] && !mark[v]){
                solve(v);
            }
        }
    }
    int main(){
        while(~scanf("%d%d", &n, &m)){
            init();
            for(int i = 1; i < n; i ++){
                scanf("%d%d", &x, &y);
                V[x].push_back(y);
                V[y].push_back(x);
            }
            deep[1] = f[1][0] = 1;
            dfs(1), cal();
            for(int i = 0; i < m; i ++){
                scanf("%d%d", &g[i].x, &g[i].y);
                g[i].p = LCA(g[i].x, g[i].y);
            }
            int res = 0;
            sort(g, g+m);
            for(int i = 0; i < m; i ++){
                if(!mark[g[i].x] && !mark[g[i].y]){
                    res ++;
                    solve(g[i].p);
                }
            }
            printf("%d
    ", res);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    HDU 1102 Constructing Roads
    HDU 1285 确定比赛名次。
    最小生成树 HDU 各种畅通工程的题,prim和kru的模板题
    HDU Jungle Roads 1301 最小生成树、
    并查集小结(转)
    HDU hdu 2094 产生冠军 拓扑排序 判定环
    模运算(转)
    拓扑排序(主要是确定环和加法) HDU 2647 Reward
    HDU 1372 Knight Moves 简单BFS
    用计算机模型浅析人与人之间沟通方式 (一)如何谈话
  • 原文地址:https://www.cnblogs.com/microcodes/p/12732276.html
Copyright © 2011-2022 走看看