• SDOI2019热闹又尴尬的聚会


    P5361 [SDOI2019]热闹又尴尬的聚会

    出题人用脚造数据系列

    只要将(p)最大的只求出来,(q)直接随便rand就能过

    真的是

    我们说说怎么求最大的(p),这个玩意具有很明显的单调性的吧

    直接二分一下(p)的值,然后将其和他所以相连的所有度数(>=p)加进去,

    可能最后有一些的点的实际度数(<=p)

    我们就把他的贡献减掉,再出现再减

    每个点只会入队一次

    数据太弱,(q)直接随机吧

    时间复杂度(O(T(nlogn+rand))

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<iostream>
    #include<algorithm>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<vector>
    #pragma GCC optimize(2)
    #define LL long long
    #define mk make_pair
    #define pii pair<int,int>
    using namespace std;
    const int N = 1e5 + 3;
    const int M = 2e5 + 3;
    struct edge{
        int to;
        int nxt;	
    }e[M << 2];
    int num[N];
    int n,m,T,dis,tot;
    int head[N],d[N],need[N];
    bool book[N],gg[N];
    vector <int> G1,G2;
    int p,q;
    inline char nc(){
        #define SIZE 100000
        static char buf[SIZE],*p1 = buf+SIZE,*pend = buf+SIZE;
        if(p1 == pend){
            p1 = buf;pend = buf+fread(buf,1,SIZE,stdin);
            if(p1 == pend) return -1;
        }
        return *p1++;
        #undef SIZE
    }
    inline int read(){
        int x = 0;int flag = 0;
        char ch = nc();
        while(!isdigit(ch)){
            if(ch == '-') flag = 1;
            ch = nc();
        }
        while(isdigit(ch)){
            x = (x<<1) + (x<<3) + (ch^'0');
            ch = nc();
        }
        if(flag) x = -x;
        return x;
    }
    inline void add(int x,int y){
        e[++tot].to = y;
        e[tot].nxt = head[x];
        head[x] = tot;
    }
    inline bool check(int mid){
        queue <int> qq;
        for(int i = 1;i <= n;++i){book[i] = 0;need[i] = 0;gg[i] = 0;}
        for(int i = 1;i <= n;++i)
            if(d[i] >= mid) qq.push(i);
        while(!qq.empty()){
            int k = qq.front();qq.pop();
            for(int i = head[k];i;i = e[i].nxt){
                int y = e[i].to;
                if(d[y] < mid) continue;
                need[y]++;
            }
        }
        for(int i = 1;i <= n;++i) if(need[i] < mid) qq.push(i);
        while(!qq.empty()){
            int k = qq.front();qq.pop();
            gg[k] = 1;
            for(int i = head[k];i;i = e[i].nxt){
                int y = e[i].to;
                if(d[y] < mid) continue;
                need[y]--;
                if(need[y] < mid && !gg[y]) gg[y] = 1,qq.push(y);
            }
        }
        bool flag = 0;
    //	cout << mid << endl;
    //		for(int i = 1;i <= n;++i) cout << need[i] << " ";cout << endl;
        for(int i = 1;i <= n;++i) if(!gg[i] && need[i] >= mid) flag = 1;
        if(flag){
            G1.clear();
            p = mid;
            for(int i = 1;i <= n;++i) if(need[i] >= mid) G1.push_back(i);
        }
        return flag;
    }
    inline int work(){
        int x;
        random_shuffle(num + 1,num + n + 1);
        int ans = 0;
        x = num[1];
        for(int i = 1;i <= n;++i) book[i] = 0,gg[i] = 0;
        for(int i = head[x];i;i = e[i].nxt){
            int y = e[i].to;
            book[y] = 1;
        }
        gg[x] = 1,book[x] = 1;
        //ans = 1;
        for(int i = 1;i <= n;++i){
            if(book[num[i]]) continue;
            book[num[i]] = 1;
            gg[num[i]] = 1;
            ans++;
            for(int j = head[num[i]];j;j = e[j].nxt){
                int y = e[j].to;
                if(book[y]) continue;
                book[y] = 1;
            }
        }
        if(ans) ans++;
        return ans;
    }
    int main(){
    
    
        T = read();
        //cout << 1 << endl;
        while(T--){
            n = read(),m = read();
            for(int i = 1;i <= n;++i) num[i] = i;
            tot = 0;
            for(int i = 1;i <= n;++i) head[i] = 0,d[i] = 0;
            for(int i = 1;i <= m;++i){
                int x = read(),y = read();
                add(x,y);
                add(y,x);
                d[x]++,d[y]++;
            }
            //continue; 
            int l = 1,r = n,ans = 1;
            while(l <= r){
                int mid = (l + r) >> 1;
            //	cout << mid << endl;
                if(check(mid)) ans = mid,l = mid + 1;
                else r = mid - 1;	
            }
        //	cout << p <<endl; 
        //	continue;
            while(1){//cout << "GG" << endl;
                q = work();
                if(p >= n / (q + 1) && q >= n / (p + 1)){
                    G2.clear();
                    for(int i = 1;i <= n;++i)if(gg[i]) G2.push_back(i);
                    break;
                }
            }
        //	printf("p:%d q:%d
    ",p,q);
            printf("%d ",(int)G1.size());
            for(int i = 0;i < (int)G1.size();++i) printf("%d ",G1[i]);printf("
    ");
            printf("%d ",(int)G2.size());
            for(int i = 0;i < (int)G2.size();++i) printf("%d ",G2[i]);printf("
    ");
        }	
        return 0;	
    }
    
  • 相关阅读:
    bootstrap-select 下拉多选组件
    Spring Boot学习笔记----POI(Excel导入导出)
    Spring boot 导出Excel
    drf 关键配置
    VCL界面开发工具—DevExpress VCL控件全新发布v19.2.6
    Web界面开发工具!Kendo UI for jQuery数据管理之网格列宽
    WPF应用界面开发技巧放送!DevExpress Breadcrumb控件
    Winforms平台界面开发技巧,如何快速掌握Filter Editor(二)
    ASP.NET Core界面开发,DevExpress v19.2增强富文本编辑器功能
    VCL界面开发工具!DevExpress VCL v19.2.5全新出发
  • 原文地址:https://www.cnblogs.com/wyxdrqc/p/10847965.html
Copyright © 2020-2023  润新知