一群牛有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;
}
}