题意:
给一个无向图,定义pair(u, v),使得任意k(k != u, v),k到u,v都有边或者k到u,v都无边
求pair的数目。 (u,v)和(v,u)算两个不同的pair。
思路:
对点u,让它的相邻点集为W(u),对于pair(u, v) ,可以分为两类
if (u, v)存在直接相连的边
则 W(u) - v = W(v) - u
else
W(u) = W(v)
而判断两个点集相不相等我们可以采取hash,这里数据量不是很大,hash函数也很好构造,给每个点赋一个点权就好了。
代码:
#include<bits/stdc++.h>
#define ll long long
#define pi acos(-1)
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define rep(i,x,n) for(int i=x;i<n;i++)
#define per(i,n,x) for(int i=n;i>=x;i--)
using namespace std;
typedef pair<int,int>P;
const int MAXN=1000010;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
vector<int>g[MAXN];
P p[MAXN];
ll w[MAXN],hh[MAXN];
void init()
{
hh[0]=1;
for(int i=1;i<MAXN;i++)
hh[i]=hh[i-1]*1007;
}
int main()
{
std::ios::sync_with_stdio(0);
int n,m,u,v;
init();
cin>>n>>m;
for(int i=0;i<m;i++)
{
cin>>u>>v;
p[i]=P(u,v);
w[u]+=hh[v];
w[v]+=hh[u];
}
ll ans=0;
for(int i=0;i<m;i++)
{
if(w[p[i].first]-hh[p[i].second]==w[p[i].second]-hh[p[i].first])
ans++;
}
sort(w+1,w+1+n);
int pre=1;
for(int i=2;i<=n;i++)
{
if(w[i]!=w[i-1])
{
ans+=(1ll*(i-pre)*(i-1-pre))/2;//计算W()相同的点集合内有多少个无序对
pre=i;
}
}
ans+=(1ll*(n+1-pre)*(n-pre))/2;
cout<<ans;
return 0;
}