http://codeforces.com/gym/101630/attachments
按链长度降序排序 一条条的向树上着色 每次着色之前先看当前链上是不是同一种颜色 线段树维护一下 是的话就更新 不是一种颜色 那就说明有冲突
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int maxn=1e5+10;
struct node1
{
int v;
int next;
};
struct node2
{
int u,v,len;
};
map <pii,bool> mp;
node1 edge[2*maxn];
node2 pre[maxn];
int clr[4*maxn],flag[4*maxn],laz[4*maxn];
int first[maxn],fa[maxn],deep[maxn],sum[maxn],son[maxn],top[maxn],mp1[maxn],mp2[maxn];
int n,q,num,gou1,gou2;
bool cmp(node2 n1,node2 n2)
{
return n1.len>n2.len;
}
void addedge(int u,int v)
{
edge[num].v=v;
edge[num].next=first[u];
first[u]=num++;
}
void dfsI(int cur)
{
int i,v;
sum[cur]=1,son[cur]=-1;
for(i=first[cur];i!=-1;i=edge[i].next){
v=edge[i].v;
if(v!=fa[cur]){
fa[v]=cur,deep[v]=deep[cur]+1;
dfsI(v);
sum[cur]+=sum[v];
if(son[cur]==-1||sum[son[cur]]<sum[v]) son[cur]=v;
}
}
}
void dfsII(int cur,int tp)
{
int i,v;
num++;
top[cur]=tp,mp1[cur]=num,mp2[num]=cur;
if(son[cur]==-1) return;
dfsII(son[cur],tp);
for(i=first[cur];i!=-1;i=edge[i].next){
v=edge[i].v;
if(v!=fa[cur]&&v!=son[cur]) dfsII(v,v);
}
}
int getlca(int u,int v)
{
while(top[u]!=top[v]){
if(deep[top[u]]<deep[top[v]]) swap(u,v);
u=fa[top[u]];
}
if(deep[u]<deep[v]) return u;
else return v;
}
void pushup(int cur)
{
if(flag[2*cur]==1&&flag[2*cur+1]==1&&clr[2*cur]==clr[2*cur+1]){
clr[cur]=clr[2*cur];
flag[cur]=flag[2*cur];
}
else flag[cur]=0;
}
void pushdown(int cur)
{
if(laz[cur]!=-1){
clr[2*cur]=laz[cur],flag[2*cur]=1,laz[2*cur]=laz[cur];
clr[2*cur+1]=laz[cur],flag[2*cur+1]=1,laz[2*cur+1]=laz[cur];
laz[cur]=-1;
}
}
void build(int l,int r,int cur)
{
int m;
laz[cur]=-1;
if(l==r){
clr[cur]=0,flag[cur]=1;
return;
}
m=(l+r)/2;
build(l,m,2*cur);
build(m+1,r,2*cur+1);
pushup(cur);
}
void query(int pl,int pr,int l,int r,int cur)
{
int m;
if(pl<=l&&r<=pr){
if(flag[cur]){
if(gou2==-1) gou2=clr[cur];
else{
if(gou2!=clr[cur]) gou1=0;
}
}
else gou1=0;
return;
}
pushdown(cur);
m=(l+r)/2;
if(pl<=m) query(pl,pr,l,m,2*cur);
if(pr>m) query(pl,pr,m+1,r,2*cur+1);
}
void update(int pl,int pr,int val,int l,int r,int cur)
{
int m;
if(pl<=l&&r<=pr){
clr[cur]=val,flag[cur]=1,laz[cur]=val;
return;
}
pushdown(cur);
m=(l+r)/2;
if(pl<=m) update(pl,pr,val,l,m,2*cur);
if(pr>m) update(pl,pr,val,m+1,r,2*cur+1);
pushup(cur);
}
bool solve(int id,int u,int v)
{
gou1=1,gou2=-1;
while(top[u]!=top[v])
{
if(deep[top[u]]<deep[top[v]]) swap(u,v);
query(mp1[top[u]],mp1[u],1,n,1);
if(!gou1) return 0;
update(mp1[top[u]],mp1[u],id,1,n,1);
u=fa[top[u]];
}
if(deep[u]<deep[v]) swap(u,v);
query(mp1[v],mp1[u],1,n,1);
if(!gou1) return 0;
update(mp1[v],mp1[u],id,1,n,1);
return 1;
}
int main()
{
pii tmp;
int i,u,v,lca;
scanf("%d%d",&n,&q);
memset(first,-1,sizeof(first));
num=0;
for(i=1;i<=n-1;i++){
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
i=0;
while(q--){
scanf("%d%d",&u,&v);
if(u>v) swap(u,v);
tmp=make_pair(u,v);
if(!mp[tmp]){
mp[tmp]=1;
i++;
pre[i].u=u,pre[i].v=v;
}
}
q=i;
fa[1]=-1,deep[1]=1;
dfsI(1);
num=0;
dfsII(1,1);
build(1,n,1);
for(i=1;i<=q;i++){
lca=getlca(pre[i].u,pre[i].v);
pre[i].len=deep[pre[i].u]+deep[pre[i].v]-2*deep[lca];
}
sort(pre+1,pre+q+1,cmp);
for(i=1;i<=q;i++) if(!solve(i,pre[i].u,pre[i].v)) break;
if(i==q+1) printf("Yes\n");
else printf("No\n");
return 0;
}