vijos2054 SDOI2019 热闹的聚会与尴尬的聚会

题目链接

思路

首先观察题目最后的式子\(\lfloor \frac{n}{p + 1} \rfloor \le q\) 并且\(\lfloor \frac{n}{q+1} \rfloor \le p\)。

这个式子其实就是告诉我们\(p\)和\(q\)都要尽量大。

然后这道题就可以分成两个小题:

1.求一个子图,使得图中最小度数最大。

2.求最大独立集。

先看第一个问题:

可以贪心的每次将度数最小的点删去。剩下的点中度数最小的那个就是当前图的贡献。然后找一个最大的贡献就是答案。

第二个问题

求一般图的最大独立集。。。不太可能。

但是这个题目的限制并没有这么严格。只要满足\(\lfloor \frac{n}{p + 1} \rfloor \le q\)即可。

每次将度数最小的点加入独立集。然后将与该点所连的点全部删去。

可以发现,这样加到独立集中点的度数一定小于等于\(p\)(否则p就可以更大了)。所以每次最多删去\(p\)个点。最少可以删\(\lceil \frac{n}{p} \rceil\)次。也就是说最少可以加入这些点。所以这种做法肯定是满足\(\lfloor \frac{n}{p + 1} \rfloor \le q\)的。

代码

/*
* @Author: wxyww
* @Date:   2019-05-11 14:54:21
* @Last Modified time: 2019-05-11 15:27:46
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 100010;
#define pi pair<int,int>
ll read() {
    ll x=0,f=1;char c=getchar();
    while(c<'0'||c>'9') {
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9') {
        x=x*10+c-'0';
        c=getchar();
    }
    return x*f;
}
priority_queue<pi,vector<pi>,greater<pi> >q;
struct node {
    int v,nxt;
}e[N << 1];
int head[N],ejs;
void add(int u,int v) {
    e[++ejs].v = v;e[ejs].nxt = head[u];head[u] = ejs;
}
int vis[N],du[N],tsd[N],bz[N],ans[N],anss[N];
int main() {
    // freopen("day2t1.in","r",stdin);
    int T = read();
    while(T--) {

        memset(vis,0,sizeof(vis));
        memset(du,0,sizeof(du));
        memset(bz,0,sizeof(bz));
        ejs = 0;memset(head,0,sizeof(head));

        int n = read(),m = read();
        for(int i = 1;i <= m;++i) {
            int u = read(),v = read();
            add(u,v);add(v,u);
            du[u]++,du[v]++;
        }

        for(int i = 1;i <= n;++i) tsd[i] = du[i];

        for(int i = 1;i <= n;++i) q.push(make_pair(du[i],i));

        int ansjs = 0,js = 0,mx = 0;
        while(!q.empty()) {
            int d = q.top().first,u = q.top().second;
            q.pop();
            vis[u] = 1;
            if(du[u] != d) continue;
            if(d > mx) {
                // puts("!!!");
                // printf("%d\n",js);
                mx = d;
                ansjs = js;
            }
            ans[++js] = u;
            for(int i = head[u];i;i = e[i].nxt) {
                int v = e[i].v;
                if(vis[v]) continue;
                du[v]--;q.push(make_pair(du[v],v));
            }
        }
        memset(vis,0,sizeof(vis));
        for(int i = 1;i <= n;++i) q.push(make_pair(tsd[i],i));
        js = 0;
        while(!q.empty()) {
            int u = q.top().second,d = q.top().first;
            q.pop();
            if(vis[u]) continue;
            vis[u] = 1;
            anss[++js] = u;
            if(d != tsd[u]) continue;
            // puts("!!!");
            for(int i = head[u];i;i = e[i].nxt) {
                int v = e[i].v;
                // puts("!!!");
                if(vis[v]) continue;
                vis[v] = 1;
                // printf("%d\n",v);
                for(int j = head[v];j;j = e[j].nxt) {
                    int vv = e[j].v;
                    if(vis[vv]) continue;
                    --tsd[vv];q.push(make_pair(tsd[vv],vv));
                }
            }
        }
        // puts("!!");
        for(int i = 1;i <= ansjs;++i) bz[ans[i]] = 1;
        printf("%d ",n - ansjs);
        for(int i = 1;i <= n;++i) if(!bz[i]) printf("%d ",i);
        puts("");
        printf("%d ",js);
        for(int i = 1;i <= js;++i) printf("%d ",anss[i]);
        puts("");

    }

    return 0;
}

原文地址:https://www.cnblogs.com/wxyww/p/vijos2054.html

时间: 2025-01-18 05:27:21

vijos2054 SDOI2019 热闹的聚会与尴尬的聚会的相关文章

[SDOI2019] 热闹又尴尬的聚会

热闹度\(p\)子图中最小的度数,尴尬度\(q\)独立集大小,之间的约束 \[ \begin{aligned} \lfloor n/(p+1)\rfloor\le q &\rightarrow \lceil(n-p-1+1)/(p+1)\rceil\le q\&\rightarrow \lceil(n-p)/(p+1)\rceil\le q\&\rightarrow (n-p)/(p+1)\le q\&\rightarrow n-p\le pq+q\&\righta

[SDOI2019]热闹又尴尬的聚会(图论+set+构造)

据说原数据可以让复杂度不满的暴力O(Tn^2)过掉……O(Tn^2)方法类似于codeforces一场div2的E题 有一种比较好的方法:每次找出原图G中度最小的点加入q,然后将相邻的点加入新图G'.这显然能够得到一个最大的独立集.而p可以在维护度最小的点最大这一过程中,把G的所有点加入集合p.因为set带一个log,所以复杂度为O(T(n+m)logn). 证明:满足(p+1)(q+1)>n即可.删除的q节点中d的度数和满足Σ(d[i]+1)=n,其中i∈q,然后max{d[i]}q>=n,

南京别墅聚会 南京大学生别墅聚会 party

南京漫步时光别墅聚会精心推荐. 南京别墅聚会 南京别墅聚会 南京江宁大学城青春汇别墅聚会 南京仙林大学城漫享时光别墅聚会

树形动态规划 fjutoj-2392 聚会的快乐

聚会的快乐 TimeLimit:1000MS  MemoryLimit:128MB 64-bit integer IO format:%lld Problem Description 你要组织一个由你公司的人参加的聚会.你希望聚会非常愉快,尽可能多地找些有趣的热闹.但是劝你不要同时邀请某个人和他的上司,因为这可能带来争吵.给定N个人(姓名,他幽默的系数,以及他上司的名字),编程找到能使幽默系数和最大的若干个人. Input 第一行一个整数N(N<100).接下来有N行,每一行描述一个人的信息,信

聚会的快乐

题目描述 你要组织一个由你公司的人参加的聚会.你希望聚会非常愉快,尽可能多地找些有趣的热闹.但是劝你不要同时邀请某个人和他的上司,因为这可能带来争吵.给定N个人(姓名,他幽默的系数,以及他上司的名字),编程找到能使幽默系数和最大的若干个人. 输入输出格式 输入格式: 第一行一个整数N(N<100).接下来有N行,每一行描述一个人的信息,信息之间用空格隔开.姓名是长度不超过20的字符串,幽默系数是在0到100之间的整数. 输出格式: 所邀请的人最大的幽默系数和. 输入输出样例 输入样例#1: 5

南京别墅聚会,南京优质大学生别墅聚会服务

南京别墅聚会网址 www.nj-party.com 漫享时光别墅聚会 仙林大学生别墅聚会,漫派一号 http://www.nj-party.com/category/jiangning/ http://www.nj-party.com/xianlin/beautifulpie/ http://www.nj-party.com/category/xianlin/ 江宁大学生别墅聚会 南京首家融入“密室逃脱”元素聚会 水景区mini垂钓,自助烧烤 仙林大学城免费上门接送  南京别墅聚会,南京优质大学

TYOI Noip模拟赛1 [T1]聚会

聚会 [问题描述] 某OI群里面一共有n个成员,每一个人可能和其中的一些人认识,现在,群里面搞了一个聚会,已知聚会参与人数恰好是s人,并且,参加聚会的人两两都互相认识,问:参加聚会的成员有多少种不同的可能? 两个参加聚会的成员集合只要有一个人不同,就算是不同的集合 [输入格式] 第一行n,m,s表示有n个成员,m对互相认识的关系,参加聚会的人数恰好是s人. 接下来m行,每行两个整数u,v,表示u和v互相认识. [输出格式] 一个整数,表示答案. [样例输入] 5 9 3 1 3 1 4 1 5

互联网工作者都应使用智能手机

今天这篇文章有点另类,但个人觉得会非常的实在,以自己的一些亲身案例经历,给大家叙述下为何我们做互联工作的人,都应该使用智能手机.或者说我们互联网工作者都应该学习使用移动互联网来提高工作效率.当然如果有的朋友只想工作的时候才办公,平时完全不想管工作上的事情,那完全可以当我这篇文章不存在.可能这篇的文章提到的互联网工作帮助更适合一些个人站长或者互联网工作狂看吧. 一:回忆自己使用智能手机的经历. 在07年的时候我才用上了第一台智能手机,记得是多普达D700,屏幕很大,觉得用来看电影和玩游戏还不错.当

10年间我们被手机毁掉的生活,看完戳心……【转载】

10年, 你从少年变成了沧桑大叔, 但这并不是全部, 世界发生了怎样了变化? 我们今天来做一次对比. 以前手机掉在地上,赶紧看地板 现在手机掉在地上,屏碎了,心也碎了 刚学会E-mail,收到一封高兴好半天 现在电子邮箱天天都弹出一大堆邮件 可是连点开的欲望都没有 如果是一封信,肯定会很开心 以前海边度假,游泳.玩球 现在去海边度假.拍照.发朋友圈 以前,电脑很胖我很瘦 现在电脑很瘦,我胖了 小时候喊你回房间,那是小黑屋 现在的小孩回房间,那是新世界 以前过生日,亲朋好友聚一块 吹蜡烛.吃蛋糕.