Codeforces 1037E Trips

原题
题目大意:
有\(n\)个人,起初他们都不是朋友。总共有\(m\)天,每天会有两个人成为朋友。他们计划在晚上出去旅游,对于一个人,有如下两种情况:
1.要么他不出去旅游
2.要么有至少\(k\)个朋友跟他一起出去
其中\(n,m,k\)都会给出
(注意,友谊是非传递性的,比如\(a\)和\(b\)是朋友,\(b\)和\(c\)是朋友,但\(a\)和\(c\)不一定是朋友)
你的任务是,对于\(1\)到\(m\)天,输出每天晚上最多可以出去玩的人数
首先,我们将题目抽象为一张无向图,问题转化为可以动态加边,在某一刻时最多能选多少个点,\(s.t.\)被选的点中任意一点都与其他被选的点有至少\(k\)条连边。
正向不太好做,我们可以逆向考虑:
首先把所有的边都加进来。显然此时度数还小于\(k\)的点是不可能对答案有贡献了,因此要删去,同时更新一下与它相邻的点的度数。重复以上操作,直到所有点的度数都大于等于\(k\)。此时剩余点的数量就是第\(m\)天时的答案。然后我们倒着删边,并重复上述操作,然后记录一下这一天的答案。最后注意一下输出顺序就OK啦!
代码不长:

#include <bits/stdc++.h>

using namespace std;

#define N 200000

int n, m, k, from[N+5], to[N+5], deg[N+5], del[N+5], ans[N+5], cnt; //del是删除标记
set<int> G[N+5]; //存图

void d(int u) { //删除
    if(del[u] || deg[u] >= k) return ; //显然要返回嘛
    queue<int> q;
    q.push(u); //准备开始更新
    del[u] = 1;
    --cnt; //更新答案
    while(!q.empty()) {
        int x = q.front(); q.pop();
        for(auto v : G[x]) { //请食用c++11
            --deg[v]; //因为这个点被删除了,相当于它与相邻点的连边也没了,因此要把相邻点的度数减去1
            if(deg[v] < k && !del[v]) {
                q.push(v);  //准备下一次更新
                del[v] = 1;
                --cnt; //更新答案
            }
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    cin >> n >> m >> k;
    cnt = n;
    for(int i = 1, x, y; i <= m; ++i)
        cin >> x >> y, from[i] = x, to[i] = y, deg[x]++, deg[y]++, G[x].insert(y), G[y].insert(x);
    for(int i = 1; i <= n; ++i) d(i);
    ans[m] = cnt; //记录答案
    for(int i = m; i >= 1; --i) {
        if(!del[from[i]]) --deg[to[i]]; //注意,这里要特判一下,因为若连边的某一端被删除了,那另一端的度数一定已经被减掉1了
        if(!del[to[i]]) --deg[from[i]];
        G[from[i]].erase(to[i]), G[to[i]].erase(from[i]);
        d(from[i]), d(to[i]); //尝试删除
        ans[i-1] = cnt; //记录答案
    }
    for(int i = 1; i <= m; ++i) cout << ans[i] << endl;
    return 0;
}

原文地址:https://www.cnblogs.com/dummyummy/p/9588673.html

时间: 2024-11-06 11:28:44

Codeforces 1037E Trips的相关文章

Codeforces Round #416

(?_?)最近脑子不好使(虽然一直都不太好用...) A题换了三个思路,全wa了(ó﹏ò?),改了差不多15遍都有了(菜的醉死...) 最后让老大给我看看,哇,错了好多地方???????. 大佬给我改好了代码,我自己又开始改,我的小宇宙要爆发了,还好最后也改对了(菜的要撞墙了 |墙|????:)); CodeForces - 811A A. Vladik and Courtesy time limit per test 2 seconds memory limit per test 256 me

Codeforces Round #415 (Div. 2)(A,暴力,B,贪心,排序)

A. Straight «A» time limit per test:1 second memory limit per test:256 megabytes input:standard input output:standard output Noora is a student of one famous high school. It's her final year in school — she is going to study in university next year.

【codeforces 718E】E. Matvey&#39;s Birthday

题目大意&链接: http://codeforces.com/problemset/problem/718/E 给一个长为n(n<=100 000)的只包含‘a’~‘h’8个字符的字符串s.两个位置i,j(i!=j)存在一条边,当且仅当|i-j|==1或s[i]==s[j].求这个无向图的直径,以及直径数量. 题解:  命题1:任意位置之间距离不会大于15. 证明:对于任意两个位置i,j之间,其所经过每种字符不会超过2个(因为相同字符会连边),所以i,j经过节点至多为16,也就意味着边数至多

Codeforces 124A - The number of positions

题目链接:http://codeforces.com/problemset/problem/124/A Petr stands in line of n people, but he doesn't know exactly which position he occupies. He can say that there are no less than a people standing in front of him and no more than b people standing b

Codeforces 841D Leha and another game about graph - 差分

Leha plays a computer game, where is on each level is given a connected graph with n vertices and m edges. Graph can contain multiple edges, but can not contain self loops. Each vertex has an integer di, which can be equal to 0, 1 or  - 1. To pass th

Codeforces Round #286 (Div. 1) A. Mr. Kitayuta, the Treasure Hunter DP

链接: http://codeforces.com/problemset/problem/506/A 题意: 给出30000个岛,有n个宝石分布在上面,第一步到d位置,每次走的距离与上一步的差距不大于1,问走完一路最多捡到多少块宝石. 题解: 容易想到DP,dp[i][j]表示到达 i 处,现在步长为 j 时最多收集到的财富,转移也不难,cnt[i]表示 i 处的财富. dp[i+step-1] = max(dp[i+step-1],dp[i][j]+cnt[i+step+1]) dp[i+st

Codeforces 772A Voltage Keepsake - 二分答案

You have n devices that you want to use simultaneously. The i-th device uses ai units of power per second. This usage is continuous. That is, in λ seconds, the device will use λ·ai units of power. The i-th device currently has bi units of power store

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp

Codeforces Round #408 (Div. 2) B

Description Zane the wizard is going to perform a magic show shuffling the cups. There are n cups, numbered from 1 to n, placed along the x-axis on a table that has m holes on it. More precisely, cup i is on the table at the position x?=?i. The probl