どこでもドア:http://codeforces.com/problemset/problem/771/A
并查集。记录每个连通块的边数和成员数,如果每个连通块的 成员数*(成员数-1)/2==边数,那么就yes
code
const int MAX = 150010;
int uni[MAX];
LL sum_member[MAX],sum_side[MAX];
void init(int len){
for(int i=1;i<=len;i++){
uni[i]=i;
sum_member[i]=1;
sum_side[i]=0;
}
}
int get_boss(int a){
return a==uni[a]? a : uni[a]=get_boss(uni[a]);
}
int n,m;
int main()
{
cin>>n>>m;
init(n);
int a,b;
for(int i=0;i<m;i++){
cin>>a>>b;
int boss_a=get_boss(a);
int boss_b=get_boss(b);
if(boss_a!=boss_b){
sum_member[boss_b]+=sum_member[boss_a];
sum_side[boss_b]+=sum_side[boss_a]+1;
uni[boss_a]=boss_b;
}
else sum_side[boss_b]+=1;
}
bool fla=true;
for(int i=1;i<=n;i++){
if(get_boss(i)==i){
if(sum_member[i]*(sum_member[i]-1)/2!=sum_side[i]){
fla=false;break;
}
}
}
if(fla) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;
}