您的位置:首页 > 其它

HDU 4912 Paths on the tree LCA 排序贪心

2014-08-05 17:31 330 查看
题意:给定n个点 m条树上的路径

下面n-1行给出一棵树

目的:

在m条路径中选择尽可能多的路径使得选择的路径互不相交

(相交的意思是一个点在2条及2条以上的路径里出现)

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
,edgenum,dis
,fa
[20],dep
;  //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
;
bool cmp(node a, node b){
    return dep[a.lca] > dep[b.lca];
}
int vis
, 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

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: