题意:无向图问点x到y 必须经过点a和点b的点对(x,y)有多少个(1,2)(2,1)算一对
n,m<=2e5
思路:先把点a b限制掉不给访问
剩下的点分四类 维护x为起点出发经过的点的数目和
1. cnta:x为起点,经过a 不经过b
2. cntb:x为起点,经过b 不经过a
3. both:x为起点,经过a 经过b
4 点x为起点,不经过a 不经过b
如果both!=0且a b之间有边,答案就是cnta*cntb
import java.util.*;
public class Main {
static long cnta=0;
static long cntb=0;
static long both=0;
static long tp=0;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int T=sc.nextInt();
while(--T>=0){
int n=sc.nextInt();
int m=sc.nextInt();
int a=sc.nextInt();
int b=sc.nextInt();
cnta=0;cntb=0;both=0;
Vector< Vector<Integer> > g=new Vector<>();
int vis[]=new int[n+1];
for(int i=0;i<=n;i++){
vis[i]=0;
Vector<Integer>v=new Vector<>();
g.add(v);
}
int ok=0;
for(int i=1;i<=m;i++){
int u=sc.nextInt();
int v=sc.nextInt();
if((u==a&&v==b)||(u==b&&v==a)){
ok=1;continue;
}
g.get(u).add(v);
g.get(v).add(u);
}
vis[a]=1;vis[b]=1;
for(int i=1;i<=n;i++){
tp=0;
if(vis[i]==0){
int res=dfs(i,g,vis,a,b);
if(res==1)cnta+=tp;
if(res==2)cntb+=tp;
if(res==3)both+=tp;
}
}
//System.out.println("cnta:"+cnta+" cntb:"+cntb+" both:"+both);
if(both==0&&ok==0){
System.out.println(0);
}
else{
System.out.println(cnta*cntb);
}
}
}
public static int dfs(int now,Vector<Vector<Integer> >g,int vis[],int a,int b){
vis[now]=1;
tp++;
int ans=0;
for(int i=0;i<g.get(now).size();i++){
int v=g.get(now).get(i);
//System.out.println("u:"+now+" v:"+v);
if(v==a){ans|=1;}
if(v==b){ans|=2;}
if(vis[v]==0){
ans|=dfs(v,g,vis,a,b);
}
}
return ans;
}
}