本文參考
1、問題描述
給定無向圖g=(v,e),v是頂點集,e是邊集。如果u⊆⊆v,且對任意u,v∈∈u有(u,v)∈∈e,u,v是兩個頂點的符號,則稱u是g的完全子圖。g的完全子圖u是g的乙個團當且僅當u不包含在g的更大的完全子圖中。
注:最大團定義:從無向圖的頂點集中選出k個並且k個頂點之間任意兩點之間都相鄰(完全圖),最大的k就是最大團。
例子
–子集是g的乙個大小為2的完全子圖,但不是乙個團,因為它包含於g的更大的完全子圖中。、和都是g的最大團。
子集樹如下:
輸入
第一行輸入乙個數n,表示圖的頂點數
第二行到第n+1行表示圖的鄰接矩陣
50 1 0 1 1
1 0 1 0 1
0 1 0 0 1
1 0 0 0 1
1 1 1 1 0
輸出
輸出有兩行
第一行表示最優值,最大團的頂點數
第二行表示最優解,最大團中的頂點編號,每乙個編號中間有乙個空格
31 2 5
**:
#include #include #include#include/*最大團:從無向圖的頂點集中選出k個並且
k個頂點之間任意兩點之間都相鄰(完全圖),最大的k就是最大團
學習:-約束函式 頂點i到已選入的頂點集中每乙個頂點都有邊相連。
-限界函式 有足夠多的可選擇頂點使得演算法有可能在右子樹中找到更大的團*/
using namespace std;
int n;//有n個節點
int m[100][100];//鄰接矩陣
int count=0;//算最大團裡的節點個數
int bestcount=0;//最大團裡的節點個數當前最優值
int x[100];//x[i]=1代表第i個節點被加入已選擇點集
int bestx[100];//最大團裡的節點擊擇情況
void dfs(int i)
return;
}else
}if(ok==1)//說明第i個點可以被加進去,遍歷左子樹
else//說明第i個點不能被加進去,遍歷右子樹}}
}int main()
}dfs(1);
printf("%d\n",bestcount);
for(i=1;i<=n;i++)
}printf("\n");
return 0;
}
最大團問題 回溯法
題目 對於給定的無向圖,找出他的最大團 分析 圖的乙個完全子圖就是乙個團,所以找最大團,通俗點講就是在乙個無向圖中找出乙個點數最多的完全圖 任意兩點之間均有邊相鄰 採用回溯法,對於解空間的子集樹,只有當前節點和所有已選的頂點都相連,才進入左子樹 而當 當前結點加上剩下節點數比最優節點的個數多時 才進...
回溯法之最大團問題
給定無向圖 g v,e 如果 u subseteq v 且對任意 u,v in u 有 u,v in e 則稱 u 是 g 的完全子圖。完全子圖 u 是 g 的團 iff 不包含在比 g 更大的完全子圖中。g 的最大團是指在 g 中所含頂點數最多的團。設當前擴充套件節點 z 位於解空間樹的第 i 層...
演算法分析 回溯法 最大團問題
在若干點和若干連線中,找到完全子圖,即子圖中各個點都和其他點相連 有4部分 1.定義全域性變數 2.約束函式 限制生成左子樹的函式 3.遞迴函式 4.呼叫遞迴函式的函式,也可以直接寫在main 1.定義全域性變數 const int m1 5 元素數 vector vector a1 int cn1...