zoukankan      html  css  js  c++  java
  • 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;	
    }
    
  • 相关阅读:
    Educational Codeforces Round 83 --- F. AND Segments
    Educational Codeforces Round 83 --- G. Autocompletion
    SEERC 2019 A.Max or Min
    2019-2020 ICPC Southwestern European Regional Programming Contest(Gym 102501)
    Educational Codeforces Round 78 --- F. Cards
    今天我学习了一门全新的语言
    codeforces 1323D 题解(数学)
    Educational Codeforces Round 80 (Div. 2) 题解 1288A 1288B 1288C 1288D 1288E
    Educational Codeforces Round 81 (Div. 2) 题解 1295A 1295B 1295C 1295D 1295E 1295F
    Codeforces Round #617 (Div. 3) 题解 1296C 1296D 1296E 1296F
  • 原文地址:https://www.cnblogs.com/wyxdrqc/p/10847965.html
Copyright © 2011-2022 走看看