HDU 4912 Paths on the tree(LCA+貪心)

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
分析:選出最多的路徑使他們沒有公共點貪心,按深度大的優先選擇然後LCA將路徑上的點標記不能再選
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
const int INF=0x3f3f3f3f;
typedef long long LL;
const int maxn=101000;
const int maxq=101000;
int pre[maxn];
int d[maxn];
int find(int x)
{
    if(pre[x]==-1)  return x;
    return pre[x]=find(pre[x]);
}
void Union(int a,int b)
{
    a=find(a);b=find(b);
    if(a!=b)  pre[a]=b;
}
//****************
int vis[maxn],F[maxn];
int head[maxn],h[maxn];
int ans[maxq];
int tt,cnt;
struct node{
    int to,next;
}e[maxn*2];
void addedge(int a,int b)
{
    e[cnt].to=b;
    e[cnt].next=head[a];
    head[a]=cnt++;
}
//****************
struct Query{
    int from,to,next;
    int id;
}q[maxq*2],Q[maxq];
void add_query(int u,int v,int i)
{
    q[tt].to=v;q[tt].next=h[u];
    q[tt].id=i;h[u]=tt++;
    q[tt].to=u;q[tt].next=h[v];
    q[tt].id=i;h[v]=tt++;
}
//***************
void init()
{
    tt=cnt=0;CLEAR(vis,false);
    CLEAR(head,-1);CLEAR(h,-1);
    CLEAR(F,0);CLEAR(ans,0);CLEAR(pre,-1);
}
int n,m;
void LCA(int u)
{
    F[u]=u;vis[u]=true;
    for(int i=head[u];i!=-1;i=e[i].next)
    {
        int v=e[i].to;
        if(vis[v])  continue;
        d[v]=d[u]+1;
        //cout<<"fuck  "<<u<<" "<<v<<" "<<d[u]<<" "<<d[v]<<endl;
        LCA(v);Union(u,v);
        F[find(u)]=u;
    }
    for(int i=h[u];i!=-1;i=q[i].next)
    {
        int v=q[i].to;
        if(vis[v])
            ans[q[i].id]=F[find(v)];
    }
}
int cmp(Query l1,Query l2)
{
    int x=ans[l1.id];
    int y=ans[l2.id];
    return d[x]>d[y];
}
void dfs(int u)
{
    vis[u]=true;
    for(int i=head[u];i!=-1;i=e[i].next)
    {
        int to=e[i].to;
        if(vis[to]||d[to]<d[u]) continue;
        dfs(to);
    }
}
int main()
{
    int x,y;
    while(~scanf("%d%d",&n,&m))
    {
         init();
         for(int i=1;i<n;i++)
         {
             scanf("%d%d",&x,&y);
             addedge(x,y);
             addedge(y,x);
         }
         for(int i=0;i<m;i++)
         {
             scanf("%d%d",&x,&y);
             add_query(x,y,i);
             Q[i].from=x;Q[i].to=y;
             Q[i].id=i;
         }
         d[1]=0;
         LCA(1);
         sort(Q,Q+m,cmp);
         CLEAR(vis,false);
         int sum=0;
         for(int i=0;i<m;i++)
         {
             if(!vis[Q[i].from]&&!vis[Q[i].to])
             {
                 sum++;
                 dfs(ans[Q[i].id]);
             }
         }
         printf("%d\n",sum);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章