HDU 4912 Paths on the tree LCA 排序贪心

lca。。。

排个序然后暴力保平安

_(:зゝ∠)_

#pragma comment(linker, "/STACK:102400000,102400000")
#include"cstdio"
#include"iostream"
#include"set"
#include"queue"
#include"string.h"
using namespace std;
#define N 100010
struct Edge{
    int from, to, nex;
}edge[2*N];
int head[N],edgenum,dis[N],fa[N][20],dep[N];  //fa[i][x] 是i的第2^x个父亲(如果超过范围就是根)
void add(int u,int v){
    Edge E={u,v,head[u]};
    edge[edgenum] = E;
    head[u]=edgenum++;
}
void bfs(int root){
    queue<int> q;
    fa[root][0]=root;dep[root]=0;dis[root]=0;
    q.push(root);
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=1;i<20;i++)fa[u][i]=fa[fa[u][i-1]][i-1];
        for(int i=head[u]; ~i;i=edge[i].nex){
            int v=edge[i].to;if(v==fa[u][0])continue;
            dep[v]=dep[u]+1;dis[v]=dis[u]+1;fa[v][0]=u;
            q.push(v);
        }
    }
}
int Lca(int x,int y){
    if(dep[x]<dep[y])swap(x,y);
    for(int i=0;i<20;i++)if((dep[x]-dep[y])&(1<<i))x=fa[x][i];
    if(x==y)return x;
    for(int i=19;i>=0;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
    return fa[x][0];
}
void init(){memset(head, -1, sizeof head); edgenum = 0;}

int n, m;
struct node{
    int l, r, lca;
}q[N];
bool cmp(node a, node b){
    return dep[a.lca] > dep[b.lca];
}
int vis[N], tim;
int main(){
    int i, j, u, v;
    memset(vis, 0, sizeof vis);
    tim = 1;
    while(~scanf("%d %d",&n,&m)){
        init();
        tim++;
        for(i = 1; i < n; i++)
        {
            scanf("%d %d",&u,&v);
            add(u, v);
            add(v, u);
        }
        bfs(1);
        for(i = 1; i <= m; i++)
        {
            scanf("%d %d",&q[i].l, &q[i].r);
            q[i].lca = Lca(q[i].l, q[i].r);
        }
        sort(q+1, q+1+m, cmp);
        int ans = 0;
        for(i = 1; i <= m; i++)
        {
            int lca = q[i].lca;
            u = q[i].l, v = q[i].r;
            if(vis[lca] == tim)continue;
            bool ok = true;
            if(u == lca)
            {
                while(v!=lca){
                    if(vis[v]==tim){ok = false;break;}
                    v = fa[v][0];
                }
                if(ok)
                {
                    ans++;
                    v = q[i].r;
                    while(v!=lca){
                        vis[v]==tim;
                        v = fa[v][0];
                    }
                    vis[lca] = tim;
                }
            }
            else if(v==lca){
                while(u!=lca){
                    if(vis[u]==tim){ok=false;break;}
                    u = fa[u][0];
                }
                if(ok)
                {
                    ans++;
                    u = q[i].l;
                    while(u!=lca){
                        vis[u]==tim;
                        u = fa[u][0];
                    }
                    vis[lca] = tim;
                }
            }
            else {
                while(v!=lca){
                    if(vis[v]==tim){ok = false;break;}
                    v = fa[v][0];
                }
                if(ok)
                while(u!=lca){
                    if(vis[u]==tim){ok=false;break;}
                    u = fa[u][0];
                }
                if(ok)
                {
                    ans++;
                    u = q[i].l, v = q[i].r;
                    while(v!=lca){
                        vis[v]==tim;
                        v = fa[v][0];
                    }
                    while(u!=lca){
                        vis[u]==tim;
                        u = fa[u][0];
                    }
                    vis[lca] = tim;
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
/*
9 3
1 2
1 3
2 4
2 5
3 8
3 9
5 6
5 7
1 2
8 9
6 7

9 4
1 2
1 3
2 4
2 5
3 8
3 9
5 6
5 7
1 2
8 9
6 7
2 4

*/

HDU 4912 Paths on the tree LCA 排序贪心

时间: 2024-10-11 07:11:38

HDU 4912 Paths on the tree LCA 排序贪心的相关文章

hdu 4912 Paths on the tree(lca+馋)

意甲冠军:它使树m路径,当被问及选择尽可能多的路径,而这些路径不相交. 思考:贪心,比較忧伤.首先求一下每对路径的lca.依照lca的层数排序.在深一层的优先级高.那么就能够贪心了,每次选择层数最深的那一个,假设两个端点没有被标记,那么就选择这条路径,把lca的子树都标记掉. 代码: #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio>

hdu 4912 Paths on the tree(树链剖分+贪心)

题目链接:hdu 4912 Paths on the tree 题目大意:给定一棵树,和若干个通道,要求尽量选出多的通道,并且两两通道不想交. 解题思路:用树链剖分求LCA,然后根据通道两端节点的LCA深度排序,从深度最大优先选,判断两个节点均没被标 记即为可选通道.每次选完通道,将该通道LCA以下点全部标记. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include

hdu 4912 Paths on the tree(树链拆分+贪婪)

题目链接:hdu 4912 Paths on the tree 题目大意:给定一棵树,和若干个通道.要求尽量选出多的通道,而且两两通道不想交. 解题思路:用树链剖分求LCA,然后依据通道两端节点的LCA深度排序,从深度最大优先选.推断两个节点均没被标 记即为可选通道. 每次选完通道.将该通道LCA下面点所有标记. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #includ

HDU 4912 Paths on the tree

http://acm.hdu.edu.cn/showproblem.php?pid=4912 题意:给一棵树,再给一些路径,求最多有多少条路径不相交. 题解:主要是贪心的想法.用LCA处理出路径的层数,然后从最深处的节点往上找.因为节点越深,对其他路径影响度越小,相交的可能性越低.需要手动扩栈. 1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include <iostream> 3 #include

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数组的查询

hdu4912 Paths on the tree --- LCA贪心

给一棵n个结点的树,m条路径的起点和终点, 问至多可以选择多少条路径使其两两间没有公共点. 这题的主要问题是, 1.如何判断两条路径上没有交点 2.按什么策略来选 看上去感觉是最大匹配问题,但nm的范围较大问题1无法高效的解决. 画个图发现可能和LCA有关,但比赛时不知道这到底有什么用,完全没想贪心. 要选择尽量多,就是要尽量避免冲突. 我们选择一个点作为根,把给的边画出来建树就可以发现,尽量选深度大的路径可以使冲突尽量小. 于是把路径按LCA深度由大到小排序,依次和之前不冲突就可以选. 下面就

hdu.5195.DZY Loves Topological Sorting(topo排序 &amp;&amp; 贪心)

DZY Loves Topological Sorting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 866    Accepted Submission(s): 250 Problem Description A topological sort or topological ordering of a directed g

HDU 2586 + HDU 4912 最近公共祖先

先给个LCA模板 HDU 1330(LCA模板) #include <cstdio> #include <cstring> #define N 40005 struct Edge{ int x,y,d,ne; }; Edge e[N*2],e2[N*2]; int be[N],be2[N],all,all2,n,m; bool vis[N]; int fa[N]; int ancestor[N][3]; int dis[N]; void add(int x, int y, int

HDU 4912 LCA+贪心

Paths on the tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 531    Accepted Submission(s): 182 Problem Description bobo has a tree, whose vertices are conveniently labeled by 1,2,…,n. Th