题目大意:
一共有n个人,他们开始互不认识,而每天早上不认识的两个人会变成朋友。一共有m天,每天晚上有的人要去旅行,去旅行的人必须满足ta有至少k个朋友也去旅行
求每天去旅行的最大人数
题解:正向处理比较麻烦,倒不如反向处理。
先假设所有人都去,然后逐个删去不了的人。
代码:
#include<set> #include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 200050 int n,m,k,eg[N][2],ind[N],a[N]; set<int>e[N]; int ot[N],ans; void deal(int u) { if(ind[u]>=k||ot[u])return ; ot[u]=1; ans--; queue<int>q; q.push(u); while(!q.empty()) { int x = q.front(); q.pop(); for(set<int>::iterator it = e[x].begin();it!=e[x].end();it++) { int to = *it; ind[to]--; if(ind[to]>=k||ot[to])continue; ot[to]=1; ans--; q.push(to); } } } int main() { scanf("%d%d%d",&n,&m,&k); for(int f,t,i=0;i<m;i++) { scanf("%d%d",&f,&t); eg[i][0]=f,eg[i][1]=t; e[f].insert(t); e[t].insert(f); ind[f]++,ind[t]++; } ans = n; for(int i=1;i<=n;i++) deal(i); a[m]=ans; for(int i=m-1;i>=1;i--) { if(!ot[eg[i][1]])ind[eg[i][0]]--; if(!ot[eg[i][0]])ind[eg[i][1]]--; e[eg[i][0]].erase(eg[i][1]); e[eg[i][1]].erase(eg[i][0]); deal(eg[i][1]); deal(eg[i][0]); a[i]=ans; } for(int i=1;i<=m;i++)printf("%d ",a[i]); return 0; }