首页 > 其他 > 详细

Manthan, Codefest 18 (rated, Div. 1 + Div. 2) E bfs + 离线处理

时间:2019-05-05 15:48:18      阅读:102      评论:0      收藏:0      [点我收藏+]

https://codeforces.com/contest/1037/problem/E

题意

有n个人,m天,在第i天早上,x和y会成为朋友,每天晚上大家都要上车,假如一个人要上车那么他得有至少k个朋友上车,输出每天晚上上车人数

题解

  • 一个点的度数<k,他就上不了车
  • 假如一个人上不了车,那么他对他的朋友就没有了价值,就等于把边去掉
  • 离线处理,反着消边
  • 因为每条边只能走一次,所以标记边bfs

代码

#include<bits/stdc++.h>
#define MAXN 200005
#define mk make_pair
using namespace std;
int n,m,k,u[MAXN][2],in[MAXN],a[MAXN];
vector<int>G[MAXN];
queue<int>Q;
map<pair<int,int>,int>del;
int main(){
    cin>>n>>m>>k;
    for(int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        u[i][0]=x;u[i][1]=y;
        in[x]++;in[y]++;
        G[x].push_back(y);G[y].push_back(x);
    }
    int ans=n;
    for(int i=1;i<=n;i++){
        if(in[i]<k){ans--;Q.push(i);}
    }
    while(!Q.empty()){
        int u=Q.front();Q.pop();
        for(auto v:G[u]){
            if(del[mk(u,v)]==1)continue;
            del[mk(u,v)]=del[mk(v,u)]=1;
            if(in[v]<k)continue;
            in[v]--;
            if(in[v]<k){ans--;Q.push(v);}
        }
    }
    a[m]=ans;
    for(int i=m;i>1&&ans>0;i--){
        int x=u[i][0],y=u[i][1];
        if(del[mk(x,y)]==1){a[i-1]=ans;continue;}
        del[mk(x,y)]=del[mk(y,x)]=1;
        in[x]--;in[y]--;
        if(in[x]<k){ans--;Q.push(x);}
        if(in[y]<k){ans--;Q.push(y);}

        while(!Q.empty()){
        int u=Q.front();Q.pop();
        for(auto v:G[u]){
            if(del[mk(u,v)]==1)continue;
            del[mk(u,v)]=del[mk(v,u)]=1;
            if(in[v]<k)continue;
            in[v]--;
            if(in[v]<k){ans--;Q.push(v);}
        }
        }
        a[i-1]=ans;
    }
    for(int i=1;i<=m;i++)printf("%d\n",a[i]);
}

Manthan, Codefest 18 (rated, Div. 1 + Div. 2) E bfs + 离线处理

原文:https://www.cnblogs.com/VIrtu0s0/p/10813380.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!