顶点覆盖,最大团

最小权顶点覆盖问题

给 定一个赋权无向图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;
}

 

posted @ 2012-09-19 10:37  Keosu  阅读(4768)  评论(0编辑  收藏  举报