zoukankan      html  css  js  c++  java
  • Codeforces Round #109 (Div. 2) E. Double Profiles hash

    题目链接:

    http://codeforces.com/problemset/problem/155/E

    E. Double Profiles

    time limit per test 3 seconds
    memory limit per test 256 megabytes
    #### 问题描述 > You have been offered a job in a company developing a large social network. Your first task is connected with searching profiles that most probably belong to the same user. > > The social network contains n registered profiles, numbered from 1 to n. Some pairs there are friends (the "friendship" relationship is mutual, that is, if i is friends with j, then j is also friends with i). Let's say that profiles i and j (i ≠ j) are doubles, if for any profile k (k ≠ i, k ≠ j) one of the two statements is true: either k is friends with i and j, or k isn't friends with either of them. Also, i and j can be friends or not be friends. > > Your task is to count the number of different unordered pairs (i, j), such that the profiles i and j are doubles. Note that the pairs are unordered, that is, pairs (a, b) and (b, a) are considered identical. #### 输入 > The first line contains two space-separated integers n and m (1 ≤ n ≤ 106, 0 ≤ m ≤ 106), — the number of profiles and the number of pairs of friends, correspondingly. > > Next m lines contains descriptions of pairs of friends in the format "v u", where v and u (1 ≤ v, u ≤ n, v ≠ u) are numbers of profiles that are friends with each other. It is guaranteed that each unordered pair of friends occurs no more than once and no profile is friends with itself. #### 输出 > Print the single integer — the number of unordered pairs of profiles that are doubles. > > Please do not use the %lld specificator to read or write 64-bit integers in С++. It is preferred to use the %I64d specificator. #### 样例 > **sample input** > 4 1 > 1 3 > > **sample output** > 2

    题意

    给你一个n个点m条边的无向图,让你求一些顶点对(无序)(u,v),满足对于任意的k(k!=u,v),k要么到两个点都有边,要么到两个点都没边,对于(u,v)本身可以存在边也可以不存在。

    题解

    这题如果你想到用hash,思路就会很直观了!
    对于顶点u,我们把它的所有相邻的点(不包括它自己)都存起来,hash成一个x进制数ha[u](每个位对应一个节点,用加权的方式加起来)

    接下来把顶点对分成两类:
    1、顶点对之间没有边相邻:
    如果两个顶点u,v它们的ha[u]=ha[v](即它们的相邻顶点集完全一样!),那么它们就是满足的顶点对。
    2、顶点对之间没有边相邻:
    如果ha[u]+u=ha[v]+v(u会出现在ha[v]里面,v会出现在ha[u]里面),同理,它们也满足条件。

    对于有边的,一条一条统计。没边的吧ha数组排个序,扫一遍就可以了。

    代码

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #include<cstring>
    #define X first
    #define Y second
    #define mp make_pair
    using namespace std;
    
    const int maxn=1e6+10;
    typedef unsigned __int64 LL;
    
    const LL P=123;
    int n,m;
    
    LL pw[maxn];
    LL ha[maxn];
    void pre(){
    	memset(ha,0,sizeof(ha));
    	pw[0]=1;
    	for(int i=1;i<maxn;i++) pw[i]=pw[i-1]*P;
    }
    
    int main(){
    	pre();
    	scanf("%d%d",&n,&m);
    	vector<pair<int,int> > egs;
    	for(int i=0;i<m;i++){
    		int u,v; 
    		scanf("%d%d",&u,&v);
    		egs.push_back(mp(u,v));
    		ha[u]+=pw[v];
    		ha[v]+=pw[u];
    	}
    	LL ans=0;
    	for(int i=0;i<m;i++){
    		int u=egs[i].X,v=egs[i].Y;
    		if(ha[u]+pw[u]==ha[v]+pw[v]) ans++;
    	}
    	sort(ha+1,ha+n+1);
    	for(int i=1;i<n;i++){
    		if(ha[i]==ha[i+1]){
    			int ed=i;
    			while(ed+1<=n&&ha[ed]==ha[ed+1]) ed++;
    			LL len=ed-i+1;
    			ans+=len*(len-1)/2;
    			i=ed;
    		}
    	}
    	printf("%I64d
    ",ans);
    	return 0;
    }
  • 相关阅读:
    SQL 三种Join关联示例
    EntityFramework 更新 整个记录全部字段不确定字段
    C# 生成Excel 报错COMException(0x800A03EC)
    EntityFramework4 几种报错解决方法
    Machine learning lecture2 note
    谷歌360度街景拍摄车对日本核电站污染隔离区进行拍摄
    android电池电量状态代码
    唠骚 2013年终奖
    互联网手机的围城:小米顶多再风光一年(转载)
    AIX下c3p0连接池问题
  • 原文地址:https://www.cnblogs.com/fenice/p/5694115.html
Copyright © 2011-2022 走看看