clique——集团
题目描述
知识点
图
实现
码前思考
整体分两步走:
- 判断是否是Clique;
- 判断是否是Maximal Clique。
此外需要注意一些细节:
- 题中给的结点数很小,因此直接使用邻接矩阵就好了,不需要使用邻接表;
整个题目的解法就是普通思路,没有什么特别需要思考的地方。
代码实现
//采用邻接矩阵进行求解
#include "bits/stdc++.h"
using namespace std;
const int maxn = 210;
bool G[maxn][maxn];
bool vis[maxn];
int nv;
int ne;
int m;
int k;
vector<int> subset;
int main(){
fill(G[0],G[0]+maxn*maxn,false);
scanf("%d %d",&nv,&ne);
for(int i=0;i<ne;i++){
int u;
int v;
scanf("%d %d",&u,&v);
G[u][v] = true;
G[v][u] = true;
}
scanf("%d",&m);
for(int i=0;i<m;i++){
subset.clear();
fill(vis,vis+maxn,false);
scanf("%d",&k);
for(int j=0;j<k;j++){
int u;
scanf("%d",&u);
vis[u] = true;
subset.push_back(u);
}
//接下来进行判断,首先是判断是否是Clique
bool isC = true;
for(int j=0;j<subset.size()&&isC==true;j++){
for(int k=j+1;k<subset.size();k++){
// printf("subset[j]:%d subset[k]:%d\n",subset[j],subset[k]);
if(G[subset[j]][subset[k]] == false){
isC=false;
break;
}
}
}
//接下来判断
if(isC == false){
printf("Not a Clique\n");
}else{
bool isM = true;
for(int j=1;j<=nv&&isM==true;j++){
//表示不是子集中的点
if(vis[j] == false){
bool isAll = true;
for(int k=0;k<subset.size();k++){
if(G[j][subset[k]] == false){
isAll = false;
break;
}
}
if(isAll){
isM = false;
}
}
}
if(isM){
printf("Yes\n");
}else{
printf("Not Maximal\n");
}
}
}
return 0;
}
码后反思
- 柳神的代码:
#include <iostream> #include <vector> using namespace std; int e[210][210]; int main() { int nv, ne, m, ta, tb, k; scanf("%d %d", &nv, &ne); for (int i = 0; i < ne; i++) { scanf("%d %d", &ta, &tb); e[ta][tb] = e[tb][ta] = 1; } scanf("%d", &m); for (int i = 0; i < m; i++) { scanf("%d", &k); vector<int> v(k); int hash[210] = {0}, isclique = 1, isMaximal = 1; for (int j = 0; j < k; j++) { scanf("%d", &v[j]); hash[v[j]] = 1; } for (int j = 0; j < k; j++) { if (isclique == 0) break; for (int l = j + 1; l < k; l++) { if (e[v[j]][v[l]] == 0) { isclique = 0; printf("Not a Clique\n"); break; } } } if (isclique == 0) continue; for (int j = 1; j <= nv; j++) { if (hash[j] == 0) { for (int l = 0; l < k; l++) { if (e[v[l]][j] == 0) break; if (l == k - 1) isMaximal = 0; } } if (isMaximal == 0) { printf("Not Maximal\n"); break; } } if (isMaximal == 1) printf("Yes\n"); } return 0; }
二刷代码
没有什么需要特殊思考的地方,就没有码代码了;