Codeforces 1037E Trips 图论,人类智慧

文章目录


题目链接

题意

每天早上有两人成为朋友,朋友之间不会传递;每天晚上举行一次聚会,对每个人来说他如果参加聚会,则不少于 k k k个他的朋友必须参加聚会.问每天晚上能参加聚会的最多人数.

题解

倒过来考虑,每天早上让一对朋友关系破裂.
则如果一个人没有 k k k个朋友,我们可以直接把他从聚会名单里面删掉,因为对任何一个人都能找到某一天使这天之前他都不能参加聚会,这天之后都能参加,这种方法显然正确.
当删除一个人之后,我们搜他的所有朋友,如果此时有朋友的朋友的数量小于 k k k个,我们可以进行连锁删除.
最后正向输出聚会名单的人数就可以了.
谢谢大家.
我唯一的疑问就是

void del(int x) {
  if (g[x].size()<*u) {
    s.erase(x);
    for (auto i:g[x]) 
      g[i].erase(x),del(i);
  }
}

void del(int x) {
  if (g[x].size()<*u&&s.erase(x)) 
    for (auto i:g[x]) 
      g[i].erase(x),del(i);
}

上面的MLE了,下面的AC了,让我觉得很奇怪.
AC代码如下.

#include<bits/stdc++.h> //Ithea Myse Valgulious
using namespace std;
const int yuzu=1e6;
typedef int fuko[yuzu|10];
fuko u,v,zw;
set<int> s,g[yuzu|10];
void del(int x) {
  if (g[x].size()<*u&&s.erase(x)) 
    for (auto i:g[x]) 
      g[i].erase(x),del(i);
}
int main() {
  int n,m,i;
  scanf("%d%d%d",&n,&m,u);
  for (i=1;i<=m;++i) {
    scanf("%d%d",u+i,v+i);
    g[u[i]].insert(v[i]);
    g[v[i]].insert(u[i]);
  }
  for (i=1;i<=n;++i) s.insert(i);
  for (i=1;i<=n;++i) del(i);
  for (i=m;i;--i) {
    zw[i]=s.size();
    g[u[i]].erase(v[i]);
    g[v[i]].erase(u[i]);
    del(u[i]),del(v[i]);
  }
  for (i=1;i<=m;++i) printf("%d\n",zw[i]);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值