(并查集)Two Fairs CodeForces - 1276B

48 篇文章 0 订阅
5 篇文章 0 订阅

这题我一开始想的是缩点,然后a子树去掉有b的子树后假设有x个点,b同理有y个点,x*y就是答案,但是有点难写,我记得去年这场cf打的时候我口胡过一个做法,但现在不太记得去了,就去翻了一下,发现我当时的想法真的好,再看我刚才想的算法,惭愧惭愧

 

这就是我去年的做法,真的妙多了,删掉和ab相连的边,然后用并查集处理下联通块就好了

 There are n cities in Berland and some pairs of them are connected by two-way roads. It is guaranteed that you can pass from any city to any other, moving along the roads. Cities are numerated from 1 to n

.

Two fairs are currently taking place in Berland — they are held in two different cities a

and b (1≤a,b≤n; a≠b

).

Find the number of pairs of cities x

and y (x≠a,x≠b,y≠a,y≠b) such that if you go from x to y you will have to go through both fairs (the order of visits doesn't matter). Formally, you need to find the number of pairs of cities x,y such that any path from x to y goes through a and b

(in any order).

Print the required number of pairs. The order of two cities in a pair does not matter, that is, the pairs (x,y)

and (y,x)

must be taken into account only once.

Input

The first line of the input contains an integer t

(1≤t≤4⋅104) — the number of test cases in the input. Next, t

test cases are specified.

The first line of each test case contains four integers n

, m, a and b (4≤n≤2⋅105, n−1≤m≤5⋅105, 1≤a,b≤n, a≠b

) — numbers of cities and roads in Berland and numbers of two cities where fairs are held, respectively.

The following m

lines contain descriptions of roads between cities. Each of road description contains a pair of integers ui,vi (1≤ui,vi≤n, ui≠vi

) — numbers of cities connected by the road.

Each road is bi-directional and connects two different cities. It is guaranteed that from any city you can pass to any other by roads. There can be more than one road between a pair of cities.

The sum of the values of n

for all sets of input data in the test does not exceed 2⋅105. The sum of the values of m for all sets of input data in the test does not exceed 5⋅105

.

Output

Print t

integers — the answers to the given test cases in the order they are written in the input.

Example

Input

3
7 7 3 5
1 2
2 3
3 4
4 5
5 6
6 7
7 5
4 5 2 3
1 2
2 3
3 4
4 1
4 2
4 3 2 1
1 2
2 3
4 1

Output

4
0
1

Sponsor

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 501050;
ll fa[maxn];
ll Find(ll x)
{
    if(fa[x]==x) return x;
    else return fa[x]=Find(fa[x]);
}
void Merge(ll x,ll y)
{
    x=Find(x);y=Find(y);
    if(x!=y) fa[x]=y;
}
map<ll,ll>mp;
vector<ll>a1;vector<ll>b1;
ll visa[maxn],visb[maxn];
int main()
{
    ll t;
    scanf("%lld",&t);
    while(t--)
    {
        ll n,m,a,b;
        scanf("%lld %lld %lld %lld",&n,&m,&a,&b);
        a1.clear();b1.clear();
        for(int i=1; i<=n+10; i++) fa[i]=i,visa[i]=0,visb[i]=0;
        for(ll i=1; i<=m; i++)
        {
            ll u,v;
            scanf("%lld %lld",&u,&v);
            if((u==a&&v==b)||(u==b&&v==a)) continue;
            if(u==a)a1.push_back(v);
            if(v==a)a1.push_back(u);
            if(u==b)b1.push_back(v);
            if(v==b)b1.push_back(u);
            if(u!=a&&u!=b&&v!=a&&v!=b) Merge(u,v);
        }
        for(auto i:a1)
        {
            visa[Find(i)]=1;
            //printf("i=%lld visa[%lld]=%lld\n",i,Find(i),visa[Find(i)]);
        }
        for(auto i:b1)
        {
            visb[Find(i)]=1;
            //printf("i=%lld visb[%lld]=%lld\n",i,Find(i),visb[Find(i)]);
        }
        for(ll i=1;i<=n;i++)
        {
            visa[i]=visa[Find(i)];
            visb[i]=visb[Find(i)];
            //printf("visa[%lld]=%lld visb[%lld]=%lld\n",i,visa[i],i,visb[i]);
        }
        ll x=0,y=0,ans=0;
        for(ll i=1;i<=n;i++)
        {
            if(visa[i]==1&&visb[i]==0) x++;
            if(visa[i]==0&&visb[i]==1) y++;
        }
        ans=x*y;
        printf("%lld\n",ans);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值