题目
http://acm.hdu.edu.cn/showproblem.php?pid=1941
题意
给n个点m条边,删掉一些点后使剩下的图为完全图,要求删掉的点两两之间不能有边相连
解法
参考:Staginner: HDU 1941 Justice League
将点按度排序,从度小的点开始删除,与之相邻的点都必须保留,判断剩下的点的最小度是否等于剩下的点数-1
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 50010;
int deg[N], vis[N], pos[N];
bool cmp(int a, int b) {
return deg[a] < deg[b];
}
int main() {
int n, m;
while(~scanf("%d%d", &n, &m) && n) {
int a, b;
vector<int> v[N];
memset(deg, 0, sizeof(deg));
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= n; i++)
pos[i] = i;
for(int i = 1; i <= m; i++) {
scanf("%d %d", &a, &b);
deg[a]++, deg[b]++;
v[a].push_back(b), v[b].push_back(a);
}
sort(pos + 1, pos + n + 1, cmp);
for(int i = 1; i <= n; i++) {
int temp = pos[i];
if(!vis[temp]) {
int sz = v[temp].size();
for(int j = 0; j < sz; j++) {
vis[v[temp][j]] = 1 ;
deg[v[temp][j]] --;
}
}
}
int cnt = 0;
int _min = 0x3f3f3f3f;
for(int i = 1; i <= n; i++) {
if(vis[i]) {
cnt++;
_min = min(_min, deg[i]);
}
}
if(cnt == _min + 1)
puts("Y");
else
puts("N");
}
return 0;
}