zoukankan      html  css  js  c++  java
  • CF1037E Trips(思维)

    正难则反。动态加边比较难以维护,考虑倒着维护

    先把全部边都添加的状态维护好,之后倒着删边。

    对于每一次,如果有一个人他没有k个好友,那么他就永远不可能旅游,因此将他删除后,并且用一个队列来做因为他删除而导致的一系列后果。

    那么还在的人是都可以去旅游的,因为他们都有k个好友

    因此我们每次删一条边就把两端点做一遍上述操作,因为所有的影响都是由这两端点产生,所以我们做完了所有状态

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e6+10;
    int st[N];
    set<int> s[N];
    int n,m,k;
    struct node{
        int a,b;
    }e[N];
    int in[N];
    int ans[N];
    int cnt;
    void solve(int u){
        if(in[u]>=k||st[u])
            return ;
        st[u]=1;
        cnt--;
        queue<int> q;
        q.push(u);
        while(q.size()){
            auto t=q.front();
            q.pop();
            for(auto x:s[t]){
                in[x]--;
                if(in[x]<k&&!st[x]){
                    st[x]=1;
                    q.push(x);
                    cnt--;
                }
            }
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        cin>>n>>m>>k;
        int i;
        for(i=1;i<=m;i++){
            int a,b;
            cin>>a>>b;
            e[i]={a,b};
            in[a]++;
            in[b]++;
            s[a].insert(b);
            s[b].insert(a);
        }
        cnt=n;
        for(i=1;i<=n;i++){
            solve(i);
        }
        ans[m]=cnt;
        for(i=m;i>=1;i--){
            int a=e[i].a,b=e[i].b;
            if(!st[b]) in[a]--;
            if(!st[a]) in[b]--;
            s[b].erase(a),s[a].erase(b);
            solve(a);solve(b);
            ans[i-1]=cnt;
        }
        for(i=1;i<=m;i++){
            cout<<ans[i]<<endl;
        }
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    简单查询
    Scott用户表
    记一次Sqoop抽数据异常
    Flink+Druid构建实时OLAP的探索
    客户端埋点实时OLAP指标计算方案
    Kafka服务不可用(宕机)问题踩坑记
    实时计算-多级订单金额,及下级人数
    Apache Druid0.15.0安装方式
    superset安装文档
    Scala的常用小技巧
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13772749.html
Copyright © 2011-2022 走看看