最小權頂點覆蓋問題
給 定一個賦權無向圖G=(V,E),每個頂點v∈V都有一個權值w(v)。如果U包含於V,且對於(u,v)∈E 有u∈U 且v∈V-U,則有v∈K.如:U = {1}, 若有邊(1,2), 則有2屬於K. 若有集合U包含於V使得U + K = V, 就稱U 為圖G 的一個頂點覆蓋。G 的最小權頂點覆蓋是指G 中所含頂點權之和最小的頂點覆蓋。
輸入: 輸入數據。第1 行有2 個正整數n 和m,表示給定的圖G 有n 個頂點和m條邊,頂點編號為1,2,…,n。第2 行有n個正整數表示n個頂點的權。接下來的m行中,每行有2 個正整數u,v,表示圖G 的一條邊(u,v)。
輸出:將計算出的最小權頂點覆蓋的頂點權之和輸出
#include<iostream>
using namespace std;
int bestw, n, m;
int e[100][100],w[100],c[100];
bool cover()
{
int i=1;
while (i<=n) {
if(c[i] == 1) {
i++;
continue;
}
int t=0;
for(int j=1; j<=n; j++)
if(e[j][i]==1&&c[j]==1&&i!=j) {
t=1;
break;
}
if(t==0)
return false;
i++;
}
return true;
}
void bs(int i,int s)
{
if(s>=bestw)
return;
if(i>n) {
if(cover( ))
bestw=s;
return;
}
c[i]=0;
bs(i+1,s);
c[i]=1;
bs(i+1,s+w[i]);
}
int main()
{
int u,v;
cin >> n >> m;
while( n!=0&&m!=0) {
for(int i=1; i<=n; i++)
cin >> w[i];
memset(c,0,sizeof(int)*n);
memset(e[0],0,sizeof(int)*n*n);
for(int k=1; k<=m; k++) {
cin >> u >> v;
e[u][v]=1;
e[v][u]=1;
}
bestw=100000;
bs(1,0);
cout << bestw << endl;
cin >> n>> m;
}
return 0;
}
最大團問題
給定無向圖G=(V, E),其中V是非空集合,稱為頂點集;E是V中元素構成的無序二元組的集合,稱為邊集。如果U∈V,且對任意兩個頂點u,v∈U有(u, v)∈E,則稱U是G的完全子圖。G的完全子圖U是G的團當且僅當U不包含在G的更大的完全子圖中。G的最大團是指G中所含頂點數最多的團。
//×î´óÍÅÎÊÌâ
#include <iostream>
using namespace std;
int f[30],e[30][30],n,cn=0,bestn,bestf[30];
void backtrack(int i)
{
if(i > n) {
if(cn > bestn){
for(int i=1;i<=n;i++)
bestf[i] = f[i];
bestn = cn;
}
return;
}
bool ok = true;
for(int j=1;j<i && ok;j++)
if(f[j] == 1 && !e[i][j])
ok = false;
if(ok){
f[i] = 1;
cn++;
backtrack(i+1);
cn--;
}
if(cn+n-i>=bestn){// Èç¹ûÖ»ÐèÕÒÒ»¸ö£¬²»ÓÃ=
f[i] = 0;
backtrack(i+1);
}
}
int main()
{
int ne,u,v;
cin >> n >> ne;
memset(f,0,sizeof(int)*n);
memset(e,0,sizeof(int)*n*n);
for(int i=1; i<=ne; i++) {
cin >> u >> v;
e[u][v]=1;
e[v][u]=1;
}
backtrack(1);
for(int i=1;i<=n;i++)
if(bestf[i] == 1)
cout << i << " ";
cout << endl << "max Clique num: "<< bestn << endl;
return 0;
}
