zoukankan      html  css  js  c++  java
  • (贪心+倍增求LCA) hdu 4912

    Paths on the tree

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 1097    Accepted Submission(s): 366


    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
     
    Author
    Xiaoxu Guo (ftiasch)
     
    Source
     
     
    从最深的公共祖先开始选择,选完之后,他的所有子节点都不可能再选,不然就重复了
     
    用倍增思想求解即可
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<map>
    #include<set>
    using namespace std;
    vector<int> e[100005];
    struct node
    {
        int x,y,z;
    }mp[100005];
    int n,m,vis[100005],deep[100005],f[100005][30],mark[100005];
    void init()
    {
        for(int i=1;i<=n;i++)
        {
            vis[i]=0;
            deep[i]=0;
            mark[i]=0;
            e[i].clear();
        }
        memset(f,0,sizeof(f));
    }
    void dfs(int u)
    {
        vis[u]=1;
        for(int i=0;i<e[u].size();i++)
        {
            int v=e[u][i];
            if(v==f[u][0])
                continue;
            if(!vis[v])
            {
                deep[v]=deep[u]+1;
                f[v][0]=u;
                dfs(v);
            }
        }
    }
    void bz()
    {
        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];
            }
        }
    }
    bool cmp(node a,node b)
    {
        return deep[a.z]>deep[b.z];
    }
    int LCA(int x,int y)
    {
        int i,j;
        if(deep[x]<deep[y])
            swap(x,y);
        for(i=0;(1<<i)<=deep[x];i++);
        i--;
        for(j=i;j>=0;j--)
        {
            if(deep[x]-(1<<j)>=deep[y])
            {
                x=f[x][j];
            }
        }
        if(x==y)
            return y;
        for(j=i;j>=0;j--)
        {
            if(f[x][j]!=f[y][j])
            {
                x=f[x][j];
                y=f[y][j];
            }
        }
        return f[x][0];
    }
    void col(int u)
    {
        mark[u]=1;
        for(int i=0;i<e[u].size();i++)
        {
            int v=e[u][i];
            if(deep[v]==deep[u]+1&&!mark[v])
                col(v);
        }
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            init();
            for(int i=1;i<n;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                e[x].push_back(y);
                e[y].push_back(x);
            }
            f[1][0]=1;
            deep[1]=1;
            dfs(1);
            bz();
            for(int i=0;i<m;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                mp[i].x=x,mp[i].y=y,mp[i].z=LCA(x,y);
            }
            int ans=0;
            sort(mp,mp+m,cmp);
            for(int i=0;i<m;i++)
            {
                if(!mark[mp[i].x]&&!mark[mp[i].y])
                {
                    ans++;
                    col(mp[i].z);
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    JAXB和XStream比较
    CButtonST类公共接口函数的介绍
    為什麼我的派生按鈕的自畫ownerdraw功能總是出錯?
    vc里使用GDI+
    cdecl, stdcall, pascal,fastcall 都有什么区别,具体是什么调用约定?
    SDK编程中窗口ID,句柄,指针三者相互转换函数
    __declspec,__cdecl,__stdcall都是什么意思?
    OnDraw()和OnPaint()
    栈 堆 区别
    MSDN for Visual Studio 6.0 高速下载地址
  • 原文地址:https://www.cnblogs.com/water-full/p/4502642.html
Copyright © 2011-2022 走看看