CodeForces - 1228D (暴力+思维+乱搞)

题意

https://vjudge.net/problem/CodeForces-1228D

有一个n个顶点m条边的无向图,在一对顶点中最多有一条边。

设v1,v2是两个不相交的非空子集,当满足以下条件时f(v1,v2)为真

  • v1中的点之间不存在边
  • v2中的点之间不存在边
  • 对于在v1v2中的每一对顶点,x在v1中,y在v2中,xy之间有边

所有点集不为空,且不相交,是否有v1,v2,v3使得f(v1,v2)、f(v2,v3)、f(v3,v1)均为真

如果有输出每个点所在的点集(1,2,3),否则输出-1

思路

这题比赛没敢开,其实就是个乱搞题,只不过细节很多。。

主要思路就是先随便选一个点插入第一个集合,然后和这个点直接相连的点肯定不能插入第一个集合,不相连的点插入第一个集合。再在不在第一个集合的点中随便选一个点,类似的扩展下去只不过要注意不能用集合1中的点,这样第二个集合就构造好了,剩余的点插入第三个集合,最后判断两两集合是否每个点都相连。这里用map<int,int> mp[N]判断是否相连比较舒服~

代码

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int N=200005;
const int mod=1e9+7;
const double eps=1e-8;
const double PI = acos(-1.0);
#define lowbit(x) (x&(-x))
vector<int> g[N];
unordered_map<int,int> mp[N];
int q[N];
int main()
{
    std::ios::sync_with_stdio(false);
    int n,m,flag=0;
    cin>>n>>m;
    for(int i=1; i<=m; i++)
    {
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
        mp[u][v]=mp[v][u]=1;
    }
    if(m==0)
    {
        cout<<-1<<endl;
        return 0;
    }
    set<int> a,b,c;
    map<int,int> t;
    a.insert(1);
    int sz=g[1].size(),bb;
    if(sz==0)
    {
        cout<<-1<<endl;
        return 0;
    }
    for(int i=1; i<=n; i++)
    {
        if(!mp[1][i])
            a.insert(i);
        else
            bb=i;
    }
    if(a.size()==n)
    {
        cout<<-1<<endl;
        return 0;
    }
    sz=g[bb].size();
    if(sz==0)
    {
        cout<<-1<<endl;
        return 0;
    }
    b.insert(bb);
    for(int i=1; i<=n; i++)
    {
        if(!mp[bb][i]&&a.find(i)==a.end())
        {
            b.insert(i);
        }
    }

    for(int i=1; i<=n; i++)
    {
        if(a.find(i)==a.end()&&b.find(i)==b.end())
        {
            c.insert(i);
        }
    }
    for(int i:a)
    {
        for(int j:b)
        {
            if(!mp[i][j])
            {
                flag=1;
                break;
            }
        }
        for(int j:c)
        {
            if(!mp[i][j])
            {
                flag=1;
                break;
            }
        }
        if(flag)
            break;
    }
    for(int i:b)
    {
        for(int j:c)
        {
            if(!mp[i][j])
            {
                flag=1;
                break;
            }
        }
    }
    if(a.size()+b.size()+c.size()!=n||
            a.size()==0||b.size()==0||c.size()==0||a.size()*b.size()+a.size()*c.size()+b.size()*c.size()!=m)
        flag=1;

    if(flag)
    {
        cout<<-1<<endl;
    }
    else
    {

        for(int i:a)
            q[i]=1;
        for(int i:b)
            q[i]=2;
        for(int i:c)
            q[i]=3;
        for(int i=1; i<=n; i++)
            cout<<q[i]<<" ";
        cout<<endl;
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/mcq1999/p/11839116.html

时间: 2024-11-07 17:28:57

CodeForces - 1228D (暴力+思维+乱搞)的相关文章

Codeforces 1077E (二分乱搞或者dp)

题意:给你一个数组,可以从中选区若干种元素,但每种元素选区的个数前一种必须是后一种的2倍,选区的任意2种元素不能相同,问可以选取最多的元素个数是多少? 思路1(乱搞):记录一下每种元素的个数,然后暴力枚举最少的元素个数,计算符合题意的最优情况. 代码: #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<map> #include<s

Codeforces 732e [贪心][stl乱搞]

/* 不要低头,不要放弃,不要气馁,不要慌张 题意: 给n个插座,m个电脑.每个插座都有一个电压,每个电脑都有需求电压. 每个插座可以接若干变压器,每个变压器可以使得电压变为x/2上取整. 有无限个变压器供应. 问最多能使得多少个插座与电脑匹配,使得电压一致. 如果有多种方案,输出需要变压器总数最小的那种. 输出匹配数量 输出每个插座需要接多少个变压器.输出每台电脑匹配哪个插座. 思路: 贪心 乱搞 先从小到大将插座排序,然后从地第一个插座开始,不断除以2上取整.不断找是否可以匹配.找到匹配就停

【bzoj2241】[SDOI2011]打地鼠  暴力+乱搞

2241: [SDOI2011]打地鼠 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 1069 Solved: 679 [Submit][Status][Discuss] Description 打地鼠是这样的一个游戏:地面上有一些地鼠洞,地鼠们会不时从洞里探出头来很短时间后又缩回洞中.玩家的目标是在地鼠伸出头时,用锤子砸其头部,砸到的地鼠越多分数也就越高. 游戏中的锤子每次只能打一只地鼠,如果多只地鼠同时探出头,玩家只能通过多次挥舞锤子的方式打

Gym 101480I Ice Igloos(思维乱搞)题解

题意:给个最多500 * 500的平面,有半径最多不为1的n个圆,现在给你1e5条线段,问你每条线段和几个圆相交,时限10s 思路: 因为半径<1,那么我其实搜索的范围只要在线段附近就好了.x1 == x2 或者 y1 == y2这个很好理解,不解释.如果是斜率> 0的,那么对于任意的x (x1 <=  x < x2),那我的范围就是floor(y)~ceil(y + 1),另一种斜率同理.然后我去数每一个格子有没有圆,能不能碰到我线段就行了.每个格子数完标记一下.可以偷个懒,标记

hdu 4972 A simple dynamic programming problem (转化 乱搞 思维题) 2014多校10

题目链接 题意:给定一个数组记录两队之间分差,只记分差,不记谁高谁低,问最终有多少种比分的可能性 分析: 类似cf的题目,比赛的时候都没想出来,简直笨到极点..... 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <vector> 7 #include &

codeforces 653C C. Bear and Up-Down(乱搞题)

题目链接: C. Bear and Up-Down time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output The life goes up and down, just like nice sequences. Sequence t1, t2, ..., tn is called nice if the following two

topcoder-srm610-div2-550(暴力乱搞)

给你一个01矩阵,求其中最大的01交替的矩阵 由于n最大才100,所以直接暴力乱搞 先求出第i行,所有列往上的合法长度,然后枚举以第j列为最左边的列,计算可以得到的最大矩阵 /************************************************************************* > File Name: 2.cpp > Author: ALex > Mail: [email protected] > Created Time: 2015年

Codeforces Amr and Chemistry(数学+乱搞)

题意:给n个数,每个数每次可以乘二或除以二(向下取整相当于左移或右移),问最少经过多少次操作可以使这n个数变相等. 思路:首先考虑每个数的可能取值,将一个数表示成s*2^k的形式,s是奇数. 那么这个数的所有可能取值为s'*2^x,(s'=s/2,(s/2)/2,.....)且s'*2^x<=100000 因为这题数据范围不大,而且每个值可能的取值不多最多几百个,所以记录1到100000每个值可能被取到的次数以及总操作数,最后从1遍历到100000取最小的ans即可 ps:个人赛这道题做了一下午

Ural 1780 Gray Code 乱搞暴力

原题链接:http://acm.timus.ru/problem.aspx?space=1&num=1780 1780. Gray Code Time limit: 0.5 secondMemory limit: 64 MB Denis, Vanya and Fedya gathered at their first team training. Fedya told them that he knew the algorithm for constructing aGray code. Cre