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
原文地址:https://www.cnblogs.com/InitRain/p/12366971.html