zoukankan      html  css  js  c++  java
  • 图论学习——最大团与最大独立集

    最大团定义:即为最大完全子图。

    给定无向图G=(V,E)。如果U是V的一个子集,且对任意u,v属于U 有(u,v)属于E,则称U 是G 的完全子图。
    G 的完全子图U是G的团当且仅当U不包含在G 的更大的完全子图中,即U就是最大完全子图。
    G 的最大团是指G中所含顶点数最多的团。

    最大独立集定义:

    独立集是指图 G 中两两互不相邻的顶点构成的集合。
    当且仅当对于U 中任意点u 和v所构成的边(u , v) 不是G 的一条边时,U 定义了一个空子图。
    当且仅当一个子集不被包含在一个更大的点集中时,该点集是图G 的一个独立集(independent set ),同时它也定义了图G 的空子图。
    最大独立集是具有最大尺寸的独立集。

    对于不同图而言,我们有以下结论:

    1、对于一般图而言: 原图的最大独立集 = 补图的最大团
    2、对于二部图而言: 最大独立集 = 点数 - 最小点覆盖(最大匹配数)



    一、对于一般图,图的最大团(最大独立集)问题是一个NP问题,因此我们可以采用搜索的方式求解问题。

    例题:Graph Coloring
    此题需要我们求解图的最大独立集,我们只需要求出补图的最大团即可(此处用的是求最大团的dfs模板,如果采用的原图建图求出来的就是最大团)

    点击查看折叠代码块
    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    const int maxn = 510;
    
    int n,m;
    bool cmp(char x[],char y[]){
    	int cnt = 0;
    	int len = strlen(x);
    	for(int i = 0;i<len;++i){
    		if(x[i]!=y[i])cnt++;
    	}
    	if(cnt>2)return true;
    	else return false;
    }
    int T;
    int bestx[maxn],x[maxn];
    int ans,cnt = 0;
    int g[maxn][maxn];
    bool place(int t){
    	bool ok = 1;
        for (int j=1;j<t;j++){
            if(x[j] && !g[t][j]){
                ok = 0;
                break;
            }
        }
        return ok;
    }
    void dfs(int t){
    	if(t>n){
    		for (int i=1;i<=n;i++){
    			bestx[i] = x[i];
    		}
    		ans=cnt;
    		return ;
    	}
    	
    	if(place(t)){
    		x[t] = 1;
    		cnt++;
    		dfs(t+1);
    		cnt--;
                    x[t] = 0;
    	}
    	
    	if(cnt+n-t>ans){
    		x[t] = 0;
    		dfs(t+1);
    	}		
    }
    
    int main(){
        cin>>T;
    	while(T--){
            scanf("%d %d",&n,&m);
            for (int i=1;i<=n;i++){
                x[i] = 0;
                for (int j=1;j<=n;j++){
                    g[i][j] = 1;
                }
            }
            cnt = 0,ans = 0;
            for (int i=1;i<=m;i++){
                int u,v;
                scanf("%d%d",&u,&v);
                g[u][v] = g[v][u] = 0;//这里建的是补图
            }
            dfs(1);
            printf("%d
    ",ans);
            int ct = 0;
            for (int i=1;i<=n;i++){
                if(bestx[i]){
                    printf("%d",i);
                    printf("%c",ct==ans?'
    ':' ');
                    ct++;    
                }
            }
        }
        return 0;
    }
    



    二、对于二分图,根据定理,我们可以采用匈牙利或者网络流的算法求出二部图的最大匹配然后求解最大独立集

    你将不再是道具,而是成为人如其名的人
  • 相关阅读:
    linux命令
    牛顿法|阻尼牛顿法|拟牛顿法|DFP算法|BFGS算法|L-BFGS算法
    借One-Class-SVM回顾SMO在SVM中的数学推导--记录毕业论文5
    【转】白话经典算法系列之七 堆与堆排序
    volatie关键字
    【转】从输入网址到显示网页的全过程分析
    CSS和HTML的一些事
    JavaScript笔记梳理
    形状文法--建筑风格分类总结
    Baidu ECharts知识梳理
  • 原文地址:https://www.cnblogs.com/wsl-lld/p/14502518.html
Copyright © 2011-2022 走看看