题目链接:Double Profiles
题意:给一个无向图,两个顶点 u, v 被称为 “doubles” 当任意 k(k≠u, k≠v) 要么与这两个点都相连,要么都不相连,问有多少对 “double”。
题解:直接 Hash 即可。分两种:第一种为包含自己和相连的顶点;第二种是不包含自己只包含相连的顶点。分别求答案并相加,但是一次 Hash 会 WA,所以就双 Hash 就好了。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const LL mod1=1e9+9; const LL mod2=1e9+7; LL pow_mod(LL a,LL n,LL mod){ LL res=1,t=a; while(n){ if(n&1) res=(res*t)%mod; t=(t*t)%mod; n/=2; } return res; } LL n,m; LL fun1[1000005],fun2[1000005],u[1000005],v[1000005]; LL Hash_fun(LL x,LL mod){ return pow_mod(n,x,mod); } LL Hash1[1000005],Hash2[1000005]; LL s1[1000005],s2[1000005],cnt1,cnt2; map<pair<LL,LL> ,LL> mp1,mp2; LL solve(){ for(LL i=1;i<=n;i++){ fun1[i]=fun2[i]=0; Hash1[i]=Hash_fun(i,mod1); Hash2[i]=Hash_fun(i,mod2); } for(LL i=1;i<=m;i++){ fun1[u[i]]=(fun1[u[i]]+Hash1[v[i]])%mod1; fun1[v[i]]=(fun1[v[i]]+Hash1[u[i]])%mod1; fun2[u[i]]=(fun2[u[i]]+Hash2[v[i]])%mod2; fun2[v[i]]=(fun2[v[i]]+Hash2[u[i]])%mod2; } LL ans=0; for(LL i=1;i<=n;i++){ ans+=mp1[make_pair(fun1[i],fun2[i])]++; ans+=mp2[make_pair((fun1[i]+Hash1[i])%mod1,(fun2[i]+Hash2[i])%mod2)]++; } return ans; } int main(){ scanf("%lld%lld",&n,&m); for(LL i=1;i<=m;i++){ scanf("%lld%lld",&u[i],&v[i]); } LL ans=solve(); printf("%lld\n",ans); return 0; }