[CF1276B] Two Fairs - DFS

给定 \(n\) 个点,\(m\) 条边,以及两个点 \(s,t\),求点对 \((a,b)\) 的个数,满足任意一条 \(a\to b\) 路径都经过 \(s,t\)

Solution

\(s\) 开始 DFS,能不经过 \(t\) 到达的点的集合记为 \(S\)

\(t\) 开始 DFS,能不经过 \(s\) 到达的点的集合记为 \(T\)

答案即为 \(|S/T||T/S|\)

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 1000005;

int n,m,s,t,S[N],T[N],a1,a2;
vector <int> g[N];

void dfs1(int p) {
    S[p]=1;
    for(int q:g[p]) if(S[q]==0&&q!=t) dfs1(q);
}

void dfs2(int p) {
    T[p]=1;
    for(int q:g[p]) if(T[q]==0&&q!=s) dfs2(q);
}

signed main() {
    ios::sync_with_stdio(false);
    int Tx;
    cin>>Tx;
    while(Tx--) {
        cin>>n>>m>>s>>t;
        for(int i=1;i<=m;i++) {
            int t1,t2;
            cin>>t1>>t2;
            g[t1].push_back(t2);
            g[t2].push_back(t1);
        }
        dfs1(s);
        dfs2(t);
        S[s]=0; S[t]=0;
        T[t]=0; T[s]=0;
        for(int i=1;i<=n;i++) if(S[i]&&!T[i]) ++a1;
        for(int i=1;i<=n;i++) if(T[i]&&!S[i]) ++a2;
        cout<<a1*a2<<endl;
        for(int i=1;i<=n;i++) S[i]=T[i]=0;
        for(int i=1;i<=n;i++) g[i].clear();
        a1=a2=0;
    }
}

猜你喜欢

转载自www.cnblogs.com/mollnn/p/12551854.html