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
1 2
贪心,从lca由深入浅地取,
能取就取,并把lca所在子树标记为无法取
#include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<functional> #include<cmath> #include<algorithm> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define ForkD(i,k,n) for(int i=n;i>=k;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define pb push_back #define mp make_pair #pragma comment(linker, "/STACK:102400000,102400000") #define MAXN (200000+10) typedef long long ll; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} int n,m; int edge[MAXN],pre[MAXN],Next[MAXN],siz=1; void addedge(int u,int v) { edge[++siz]=v; Next[siz]=pre[u]; pre[u]=siz; } void addedge2(int u,int v){addedge(u,v); addedge(v,u); } int son[MAXN],top[MAXN]; int fa[MAXN],dep[MAXN],sz[MAXN]; void dfs(int x){ Forp(x) { int v=edge[p]; if (v==fa[x]) continue; fa[v]=x; dep[v]=dep[x]+1; dfs(v); sz[x]+=sz[v]; if (sz[son[x]]<sz[v]) son[x]=v; } ++sz[x]; } int q[MAXN]; void init() { MEM(son) MEM(top) MEM(fa) MEM(dep) MEM(sz) dfs(1); int head=1,tail=1;q[1]=1; while(head<=tail) { int now=q[head++]; if (!top[now]) { for(int x=now;x;x=son[x]) top[x]=now; } Forp(now) { int v=edge[p]; if (fa[now]!=v) q[++tail]=v; } } } int lca(int u,int v) { while(1) { if (top[u]==top[v]) return dep[u]<dep[v]?u:v; if (dep[top[u]]>dep[top[v]]) u=fa[top[u]]; else v=fa[top[v]]; } } bool vis[MAXN]; void color(int x) { vis[x]=1; Forp(x) { int v=edge[p]; if (v==fa[x]||vis[v]) continue; color(v); } } bool check(int u,int v) { return !(vis[u]||vis[v]); } struct chain{ int u,v,lc; chain(){} chain(int _u,int _v,int _lc) {u=_u,v=_v,lc=_lc;} friend bool operator<(chain a,chain b){return dep[a.lc]>dep[b.lc]; } }e[MAXN]; int main() { // freopen("B.in","r",stdin); // freopen(".out","w",stdout); while(scanf("%d%d",&n,&m)==2) { MEM(edge) MEM(pre) MEM(Next) siz=1; MEM(fa) MEM(vis) For(i,n-1) { int u,v; scanf("%d%d",&u,&v); addedge2(u,v); } init(); For(i,m) { int u,v; scanf("%d%d",&u,&v); e[i]=chain(u,v,lca(u,v)); } sort(e+1,e+1+m); int ans=0; For(i,m) { if (check(e[i].u,e[i].v)) { color(e[i].lc); ++ans; } } cout<<ans<<endl; } return 0; }