【BZOJ4264】小C找朋友 解题笔记
Description
幼儿园里有
园长
Input
第一行一个数
Output
输出可能成为好J友的小
AC代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <map>
#define int long long
using namespace std;
const int N=(int)1e6+10;
int n,m,ans;
int a[N],val[N];
map<int,int>mm;
inline int read(){
int x=0;
char c=getchar();
while(c<'0' || c>'9') c=getchar();
while(c>='0' && c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x;
}
signed main(){
srand(time(0));
n=read(),m=read();
for(int i=1;i<=n;++i) val[i]=(rand()*rand()%(int)1e18*rand())+i;
for(int i=1;i<=m;++i){
int u=read(),v=read();
a[u]^=val[v],a[v]^=val[u];
}
for(int i=1;i<=n;++i){
ans+=mm[a[i]];
++mm[a[i]];
} mm.clear();
for(int i=1;i<=n;++i) a[i]^=val[i];
for(int i=1;i<=n;++i){
ans+=mm[a[i]];
++mm[a[i]];
} cout<<ans;
return 0;
}
构造一些小哈希,挺妙的。
由“对于两个(不同的)小
·若
·若
我们可以采用如下方式判断两个点所连的所有结点是否完全相同:
1.先给每个点赋一个随机权值
2.若
3.以上过程完成后,若
值得注意的是:可能有多个点的
还有两个小细节:
1.在赋随机权值时,若令
2.如何判断