#include<iostream>
#include<cstring>
#include<queue>//注意bfs,a了,但原理不明,模版未当
#include<algorithm> //hdu4912
#define N 100010
using namespace std;//我还没定义、。。。
struct Edge
{
int from,to,nex;
}edge[2*N];
struct node
{
int l,r;
int lca;
}q[N];
int head[N],edgenum,dis[N],fa[N][20],dep[N],vis[N];
int n,m,tim;
bool cmp(node a,node b)
{
return dep[a.lca]>dep[b.lca];
}
void add(int u,int v)
{
Edge E={u,v,head[u]};
edge[edgenum]=E;
head[u]=edgenum++;
}
void bfs(int root)//用bfs 我理解,但赋值部分不清楚 ,因为要一层一层找下去所以要用LCA
{
queue <int> q;
dep[root]=0;dis[root]=0;fa[root][0]=root;
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(fa[u][0]==v)continue;//逗我,这句什么意思
dis[v]=dis[u]+1;dep[v]=dep[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 main()//神奇的LCA
{
memset(vis,0,sizeof(vis));
tim=1;
int u,v;
while(~scanf("%d %d",&n,&m))
{
int ans=0;
init();
tim++;
for(int i=1;i<n;i++)
{
cin>>u>>v;
add(u,v);
add(v,u);
}
bfs(1);
for(int i=1;i<=m;i++)
{
cin>>q[i].l>>q[i].r;
q[i].lca=LCA(q[i].l,q[i].r);
}
sort(q+1,q+m+1,cmp);
//主函数也太有个性了吧
for(int 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(lca==u)
{
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(lca==v)
{
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;
}
HDU4912
最新推荐文章于 2020-04-20 14:05:09 发布