• hdu 4912 Paths on the tree(lca+馋)


    意甲冠军:它使树m路径,当被问及选择尽可能多的路径,而这些路径不相交。

    思考:贪心,比較忧伤。首先求一下每对路径的lca。依照lca的层数排序。在深一层的优先级高。那么就能够贪心了,每次选择层数最深的那一个,假设两个端点没有被标记,那么就选择这条路径,把lca的子树都标记掉。


    代码:


    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<stack>
    #include<set>
    #include<cmath>
    #include<vector>
    #define inf 0x3f3f3f3f
    #define Inf 0x3FFFFFFFFFFFFFFFLL
    #define eps 1e-9
    #define pi acos(-1.0)
    using namespace std;
    typedef long long ll;
    const int maxn=100000+10;
    struct Edge
    {
        int v,next;
        Edge(int v=0,int next=0):v(v),next(next){}
    }edges[maxn<<1];
    struct Node
    {
        int u,v,id;
        Node(int u=0,int v=0,int id=0):u(u),v(v),id(id) {}
    }node[maxn];
    int head[maxn],nEdge;
    int LCA[maxn],pa[maxn],d[maxn];
    bool vis[maxn];
    vector<pair<int,int> >querys[maxn];
    int Find(int x)
    {
        return x==pa[x]?x:pa[x]=Find(pa[x]);
    }
    void AddEdges(int u,int v)
    {
        edges[++nEdge]=Edge(v,head[u]);
        head[u]=nEdge;
        edges[++nEdge]=Edge(u,head[v]);
        head[v]=nEdge;
    }
    void dfs(int u,int fa)
    {
        pa[u]=u;
        pair<int,int>pii;
        for(int i=0;i<(int)querys[u].size();++i)
        {
            pii=querys[u][i];
            if(d[pii.first]==-1) continue;
            LCA[pii.second]=Find(pii.first);
        }
        for(int k=head[u];k!=-1;k=edges[k].next)
        {
            int v=edges[k].v;
            if(v==fa) continue;
            d[v]=d[u]+1;
            dfs(v,u);
            pa[v]=u;
        }
    }
    bool cmp(Node a,Node b)
    {
        int u=LCA[a.id];
        int v=LCA[b.id];
        return d[u]>d[v];
    }
    void Init(int n)
    {
        memset(vis,0,sizeof(vis));
        memset(head,0xff,sizeof(head));
        nEdge=-1;
        memset(d,0xff,sizeof(d));
        for(int i=0;i<=n;++i)
            querys[i].clear();
    }
    void tour(int u)
    {
        vis[u]=true;
        for(int k=head[u];k!=-1;k=edges[k].next)
        {
            int v=edges[k].v;
            if(vis[v]||d[v]<d[u]) continue;
            tour(v);
        }
    }
    int main()
    {
    //    freopen("in.txt","r",stdin);
    //    freopen("out.txt","w",stdout);
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            Init(n);
            int u,v;
            for(int i=1;i<n;++i)
            {
                scanf("%d%d",&u,&v);
                AddEdges(u,v);
            }
            for(int i=0;i<m;++i)
            {
                scanf("%d%d",&u,&v);
                querys[u].push_back(make_pair(v,i));
                querys[v].push_back(make_pair(u,i));
                node[i].u=u;node[i].v=v;
                node[i].id=i;
            }
            d[1]=0;
            dfs(1,-1);
            sort(node,node+m,cmp);
            int cnt=0;
            for(int i=0;i<m;++i)
            {
                if(!vis[node[i].u]&&!vis[node[i].v])
                {
                    cnt++;
                    tour(LCA[node[i].id]);
                }
            }
            printf("%d
    ",cnt);
        }
        return 0;
    }
    


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    newcoder 筱玛的迷阵探险(搜索 + 01字典树)题解
    str&repr的使用&format模板的自定义
    内置函数的补充与getattrebuit & item系列
    python几种常用模块
    面向对象的反射&动态导入模块
    面向对象的封装&定制数据类型
    面向对象的多态
    面向对象的继承
    面向对象的属性与方法
    面向对象的属性及类的增删改查
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4808076.html
Copyright © 2020-2023  润新知