Sicily 10482. Party Invitations

一群牛有G组小团体,主人要邀请一些牛去宴会。牛的编号从1-N,首先必须邀请1号牛;对于每个k只牛的小团体,如果邀请了其中k-1只牛,就必须邀请整个小团体的k只牛,因为它们关系很好。

最多有1000000只牛,开个数组标记是否邀请一只牛。用list保存每组小团体的成员编号。对每个小团体list,删除已经邀请的成员,如果最后剩下一只牛,就邀请它。

循环检查,直到不能再邀请到一头牛。

纯暴力,但却在一个错误上卡了很久。list的erase方法返回的指针要-1,如果不-1,会漏掉一只牛没有检查是否已邀请,因为每次循环指针都会+1。 说到底还是比较少用list,不熟悉。

很多时候的错误都是难以注意的小错误,所以掌握好基础很重要。

#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <list>
#include <queue>
#include <algorithm>
using namespace std;

bool invited[1000009];
int n,g;

int main(){
    while(cin>>n>>g){
         memset(invited,0,sizeof(invited));
         invited[1]=true;
         
         int s,temp;
         list<int> v[g];
         for(int i=0;i<g;++i){
             cin>>s;   
             for(int j=0;j<s;++j){
                 cin>>temp;
                 v[i].push_back(temp);        
             }
         }
         
         bool done=false;
         int count=1;
         while(!done){
             done=true;         
             for(int i=0;i<g;++i){
                 if(v[i].size()==1) v[i].erase(v[i].begin());
                 for(list<int>::iterator it=v[i].begin();it!=v[i].end();++it){
                      if(invited[*it]){
                           it=v[i].erase(it); 
                           --it;//就是这里错了!!!!!!!!!!!!!
                      }
                 }
                 if(v[i].size()==1){
                     list<int>::iterator it=v[i].begin();
                     if(!invited[*it]){
                     invited[*it]=true;
                     count++;}
                     done=false;
                 }
             }         
         }
         cout<<count<<endl;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值