Description
无向图中有N个节点和两类边,一类边被称为主要边,而另一类被称为附加边。Dark有N – 1条主要边,并且Dark的任意两个节点之间都存在一条只由主要边构成的路径。另外,Dark还有M条附加边。
你的任务是把Dark斩为不连通的两部分。一开始Dark的附加边都处于无敌状态,你只能选择一条主要边切断。一旦你切断了一条主要边,Dark就会进入防御模式,主要边会变为无敌的而附加边可以被切断。但是你的能力只能再切断Dark的一条附加边。现在你想要知道,一共有多少种方案可以击败Dark。注意,就算你第一步切断主要边之后就已经把Dark斩为两截,你也需要切断一条附加边才算击败了Dark。
Input
第一行包含两个整数N和M。
之后N – 1行,每行包括两个整数A和B,表示A和B之间有一条主要边。
之后M行以同样的格式给出附加边。
Output
输出一个整数表示答案。
Sample Input
4 1
1 2
2 3
1 4
3 4
Sample Output
3
Hint
对于20% 的数据,N≤100,M≤100。
对于100% 的数据,N≤100 000,M≤200 000。数据保证答案不超过2^31– 1。
Solution
对于一条附加边,可以对两点到它们的LCA之间的边产生影响
当一条主要边不受影响时,可以和任意一条附加边产生组合。
当一条主要边只受一条附加边影响时,可以与这一条附加边产生组合
当一条主要边受多条附加边影响时,删了这条主要边,仍有两条以上的边连接两边,够不成独立区域
故进行树上差分即可 (dfs序)
Code

1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define RG register int 6 #define rep(i,a,b) for(RG i=a;i<=b;i++) 7 #define per(i,a,b) for(RG i=a;i>=b;i--) 8 #define inf (1<<30) 9 #define maxn 100005 10 #define maxm 200005 11 using namespace std; 12 int n,m,cnt,id,ans; 13 int head[maxn],cf[maxn]; 14 int son[maxn],sz[maxn],fa[maxn],dep[maxn],dfn[maxn],top[maxn]; 15 struct E{ 16 int v,next; 17 }e[maxn<<1]; 18 19 inline int read() 20 { 21 int x=0,f=1;char c=getchar(); 22 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 23 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 24 return x*f; 25 } 26 27 inline void add(int u,int v) 28 { 29 e[++cnt].v=v,e[cnt].next=head[u],head[u]=cnt; 30 } 31 32 void dfs1(int u,int pa) 33 { 34 sz[u]=1,son[u]=0,fa[u]=pa,dep[u]=dep[pa]+1; 35 for(int i=head[u];i;i=e[i].next) 36 { 37 int v=e[i].v; 38 if(v==pa) continue; 39 dfs1(v,u); 40 sz[u]+=sz[v]; 41 if(sz[v]>sz[son[u]])son[u]=v; 42 } 43 } 44 45 void dfs2(int u,int tp) 46 { 47 dfn[u]=++id,top[u]=tp; 48 if(!son[u]) return; 49 dfs2(son[u],tp); 50 for(int i=head[u];i;i=e[i].next) 51 if(e[i].v!=son[u]&&e[i].v!=fa[u]) dfs2(e[i].v,e[i].v); 52 53 } 54 55 int work(int x,int y) 56 { 57 while(top[x]!=top[y]) 58 { 59 if(dep[top[x]]<dep[top[y]]) swap(x,y); 60 --cf[dfn[x]+1],++cf[dfn[top[x]]]; 61 x=fa[top[x]]; 62 } 63 if(dep[x]>dep[y]) swap(x,y); 64 ++cf[dfn[x]+1],--cf[dfn[y]+1]; 65 } 66 67 int main() 68 { 69 n=read(),m=read(); 70 RG u,v; 71 rep(i,2,n) u=read(),v=read(),add(u,v),add(v,u); 72 dfs1(1,0); 73 dfs2(1,0); 74 rep(i,1,m) 75 { 76 u=read(),v=read(); 77 work(u,v); 78 } 79 rep(i,2,n) 80 { 81 cf[i]+=cf[i-1]; 82 if(!cf[i]) ans+=m; 83 else if(cf[i]==1) ans++; 84 } 85 printf("%d ",ans); 86 return 0; 87 }