給定一個無向圖G,頂點編號爲1到Nv,Ne條邊,判斷給出的一組頂點集合是否構成該圖的一個極大徹底子圖,若是是輸出Yes,不然判斷是不是一個徹底子圖,若是是輸出Not Maximal,不然輸出Not a Clique。算法
首先得判斷輸入的集合是不是當前圖G的一個徹底子圖,這裏採用isClique函數來實現,若是是就再判斷是不是一個極大徹底子圖,這裏採用isMaximal來實現,最後就根據判斷的結果進行相應的輸出就好。函數
直接遍歷輸入集合的不一樣頂點之間是否存在不鄰接的點,若是是就返回false,不然返回true。spa
bool G[201][201];// 鄰接矩陣,判斷2點是否鄰接 bool isClique(const vector<int> &a){ for(int i:a){ for(int j:a){ if(i!=j&&!G[i][j]){ // 存在不鄰接的結點 return false; } } } return true; }
咱們使用exist標記全部輸入的結點,而後遍歷全部的頂點,只要沒有出如今輸入集合中而且與集合全部頂點都鄰接,說明不是極大徹底子圖,返回false,不然返回true。code
bool G[201][201];// 鄰接矩陣,判斷2點是否鄰接 bool exist[201];// 標記每個在subset中的結點編號 bool isMaximal(const vector<int> &a,int N){ for(int i=1;i<=N;++i){ if(exist[i]) continue; bool isAllAdjcent = true; for(int j:a){ // 得判斷i和全部的點是否鄰接 if(!G[i][j]){ isAllAdjcent = false; break; } } if(isAllAdjcent){ // 能夠擴展一個鄰接點 return false; } } return true; }
#include<cstdio> #include<vector> #include<cstring> using namespace std; bool G[201][201];// 鄰接矩陣,判斷2點是否鄰接 bool exist[201];// 標記每個在subset中的結點編號 bool isClique(const vector<int> &a){ for(int i:a){ for(int j:a){ if(i!=j&&!G[i][j]){ // 存在不鄰接的結點 return false; } } } return true; } bool isMaximal(const vector<int> &a,int N){ for(int i=1;i<=N;++i){ if(exist[i]) continue; bool isAllAdjcent = true; for(int j:a){ // 得判斷i和全部的點是否鄰接 if(!G[i][j]){ isAllAdjcent = false; break; } } if(isAllAdjcent){ // 能夠擴展一個鄰接點 return false; } } return true; } int main(){ int Nv,Ne; scanf("%d %d",&Nv,&Ne); int a,b; for(int i=0;i<Ne;++i){ scanf("%d %d",&a,&b); G[a][b] = G[b][a] = true; } int M,N; scanf("%d",&M); for(int i=0;i<M;++i){ vector<int> subset; memset(exist,0,sizeof(exist)); scanf("%d",&N); for(int j=0;j<N;++j){ scanf("%d",&a); exist[a] = true; subset.push_back(a); } if(!isClique(subset)){ printf("Not a Clique\n"); }else if(!isMaximal(subset,Nv)) { printf("Not Maximal\n"); }else { printf("Yes\n"); } } return 0; }