题目链接:
1277E Two Fairs
思路:
1.题意为a到b必须经过x和y,有多少对{a,b};
2.我们将这个问题拆解开来:
(1)有多少x想要到达b,必须经过a?
由于是无向图,我们可以将这个问题转换为,b可以到达的点中,多少个点必须经过a?
两次dfs即可;
(2)a能到达的点中,多少必须经过b?
两次dfs即可;
根据计数的知识,我们可以知道答案即为上述两个问题答案的乘积;
(需要开long long
)
代码:
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
typedef long long LL;
#define fi first
#define sc second
#define pb(a) push_back(a)
#define mp(a,b) make_pair(a,b)
#define pt(a) cerr<<a<<"---
"
#define rp(i,n) for(int i=0;i<n;i++)
#define rpn(i,n) for(int i=1;i<=n;i++)
const int maxn=2e5+99;
int n,m,a,b;
LL cnt;
vector<int> G[maxn],vv;
bool vst[maxn];
void dfs(int now){
vst[now]=true; cnt++; vv.pb(now);
for(int x:G[now]){
if(vst[x]==false) dfs(x);
}
}
void clear(){
for(int x:vv) vst[x]=false; vv.clear();
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t; cin>>t;
while(t--){
cin>>n>>m>>a>>b;
rp(i,m){
int x,y; cin>>x>>y;
G[x].pb(y); G[y].pb(x);
}
LL x,y;
cnt=0; dfs(a); clear();x=cnt; //cout<<"-----
";//pt(cnt);
vst[b]=true; cnt=0;
dfs(a); clear(); x=x-cnt-1; vst[b]=false;
cnt=0; dfs(b); clear(); y=cnt;
vst[a]=true; cnt=0;
dfs(b); clear(); y=y-cnt-1; vst[a]=false;
if(x*y<0) cout<<0<<'
';
else cout<<1ll*x*y<<'
';
rpn(x,n) G[x].clear();
}
return 0;
}