zoukankan      html  css  js  c++  java
  • cf1228 D Complete Tripartite(哈希)

    题意:

    无向简单图,无自环,无重边,n个点,m条边,请你将这n个点分为3个互相没有交集的集合。并且满足以下条件:

    1.同一个集合中的任意两点之间没有边。

    2.每个点都要与除了它这个集合以外的所有点相连。

    没有答案就输出-1,多种答案输出任意一种。

    思路:

    用hash值代表与一个点相连的 都有哪些点,

    如果出现三种hash值就没有答案;

    如果有一个点的度为0,也没有答案;

    根据哈希值,点被分为三份,如果每一份的点数+它们所连的点的点数 != n,也没有答案;

    如果同一条边相连的两个点的哈希值相同,也没有答案。

    以上条件都不满足的话,就是答案,输出即可。

    代码:

    #include <stdio.h>
    #include <queue>
    #include <string>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    #include <map>
    #include <set>
    #include <iostream>
    using namespace std;
    typedef long long int ll;
    const int maxn = 1e5 + 10;
    const int inf = 70000000;
    const ll mod = 1e9 + 7;
    const ll seed = 131;
    vector<int>mp[maxn];
    map<ll,int>s;
    ll a[maxn];
    int p[maxn];
    ll _hash[maxn];
    int main()
    {
        int n,m,x,y,num;
        while(scanf("%d%d",&n,&m) != EOF){
            s.clear();
            num = 0;
            for(int i = 1;i <= m;i++){
                scanf("%d%d",&x,&y);
                mp[x].push_back(y);
                mp[y].push_back(x);
            }
            for(int i = 1;i <= n;i++){
                sort(mp[i].begin(),mp[i].end());
                ll temp = 0;
                for(int j = 0;j < mp[i].size();j++){
                    temp = ((temp * seed) % mod + mp[i][j]) % mod;
                }
                _hash[i] = temp;
                if(s[temp] == 0){
                    num++;
                    a[num] = temp;
                    p[num] = i;
                }
                
                s[temp]++;
                if(temp == 0 || num > 3){
                    printf("-1
    ");
                    return 0;
                }
            }
    
            for(int i = 1;i <= 3;i++){
                if(s[a[i]] + mp[p[i]].size() != n){
                    printf("-1
    ");
                    return 0;
                }
            }
    
            for(int i = 1;i <= n;i++){
                for(int j = 0;j < mp[i].size();j++){
                    x = i;
                    y = mp[i][j];
                    if(_hash[x] == _hash[y]){
                        printf("-1
    ");
                        return 0;
                    }
                }
            }
    
            for(int i = 1;i <= n;i++){
                if(_hash[i] == a[1])
                    printf("1 ");
                else if(_hash[i] == a[2])
                    printf("2 ");
                else
                    printf("3 ");
            }   
            puts("");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    乘法相关
    hdu 1211 RSA (逆元)
    hdu 1811 Rank of Tetris (拓扑 & 并查集)
    hdu 2153 仙人球的残影
    hdu 1426 Sudoku Killer (dfs)
    hdu 2510 符号三角形 (DFS+打表)
    zoj 1002 Fire Net (二分匹配)
    hdu 1172 猜数字
    hdu 1728 逃离迷宫 (bfs)
    《Effective C++》笔记:III(转载)
  • 原文地址:https://www.cnblogs.com/InitRain/p/12366971.html
Copyright © 2011-2022 走看看