Codeforces Round #606 E

题:https://codeforces.com/contest/1277/problem/E

题意:给定无向图,求有多少个pair之间的简单路径一定要经过给定的点a和b(pair中任何一个都不是a或b)

分析:分别从俩个点开始dfs ,以从a为起点为例,每次若dfs到了b,我们可以想象,剩余没遍历到的点一定是与这些点不联通的,也就是相当于a的其余子树。得解

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define pi pair<int,int>
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=1e18;
const int M=1e6+6;
const int mod=1e9+7;
vector<int>g[M];
int vis[M];
int flag;
ll nowsum;
void dfs(int u,int sign){
    nowsum++;
    vis[u]=1;
    if(u==sign)
        flag=1;
    for(auto v:g[u]){
        if(!vis[v])
            dfs(v,sign);
    }
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n,m,a,b;
        scanf("%d%d%d%d",&n,&m,&a,&b);
        for(int i=0;i<=n;i++)
            vis[i]=0,g[i].clear();
        while(m--){
            int u,v;
            scanf("%d%d",&u,&v);
            g[u].pb(v);
            g[v].pb(u);
        }
        flag=0;
        ll suma=0,sumb=0;
        vis[a]=1;
        for(auto v:g[a]){
            nowsum=0;
            dfs(v,b);
            if(flag){
                suma=1ll*(n-nowsum-1);
                break;
            }
        }
      //  cout<<suma<<endl;
        flag=0;

        for(int i=0;i<=n;i++)
            vis[i]=0;
        vis[b]=1;
        for(auto v:g[b]){
            nowsum=0;
            dfs(v,a);
            if(flag){
                sumb=1ll*(n-nowsum-1);
                break;
            }
        }
        printf("%I64d\n",suma*sumb);
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/starve/p/12044538.html