頂點覆蓋,最大團


最小權頂點覆蓋問題

給 定一個賦權無向圖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是非空集合,稱為頂點集;EV中元素構成的無序二元組的集合,稱為邊集。如果UV,且對任意兩個頂點uvU有(u, v)∈E,則稱UG的完全子圖。G的完全子圖UG的團當且僅當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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM