zoukankan      html  css  js  c++  java
  • HDU Maximum Clique (最大团)

    题面

    Given a graph G(V, E), a clique is a sub-graph g(v, e), so that for all vertex pairs v1, v2 in v, there exists an edge (v1, v2) in e. Maximum clique is the clique that has maximum number of vertex.

    Input
    Input contains multiple tests. For each test: The first line has one integer n, the number of vertex. (1 < n <= 50) The following n lines has n 0 or 1 each, indicating whether an edge exists between i (line number) and j (column number). A test with n = 0 signals the end of input. This test should not be processed.

    Output
    One number for each test, the number of vertex in maximum clique.

    Sample Input
    5
    0 1 1 0 1
    1 0 1 1 1
    1 1 0 1 1
    0 1 1 0 1
    1 1 1 1 0
    0

    Sample Output
    4

    思路

    求最大团的裸题,回溯法求一下就好了。枚举从每个点开始到最后一个点所构成的极大团,每次我们选择一个点的连边加入,然后要求不同的连边之间也存在边,这样递归搜索,就可以求出这些点的极大团点了,最后的取最大值就是最大团。

    代码实现

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<set>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define MT(x,i) memset(x,i,sizeof(x) )
    #define rev(i,start,end) for (int i=0;i<end;i++)
    #define inf 0x3f3f3f3f
    #define mp(x,y) make_pair(x,y)
    #define lowbit(x) (x&-x)
    #define MOD 1000000007
    #define exp 1e-8
    #define N 1000005 
    #define fi first 
    #define se second
    #define pb push_back
    typedef long long ll;
    typedef pair<int ,int> PII;
    ll gcd (ll a,ll b) {return b?gcd (b,a%b):a; }
    const int maxn=60;
    int g[maxn][maxn];
    int vex[maxn];
    int temp[maxn][maxn];
    int n,m,ans;
    int t,tot;
    
    bool dfs (int d,int num) {
        if (num==0) {
            if (d>ans) {
                ans=d;
                return true;
            }
            return false;
        }
        
        rep (i,1,num) {
            if (d+num-i+1<=ans)  return false;
            int v=temp[d][i];
            int cnt=0;
            if (vex[v]+d<=ans) return false;
            for (int j=i+1;j<=num;j++){
                int vv=temp[d][j];
                if (g[v][vv]) temp[d+1][++cnt]=vv;
            }
            if (dfs (d+1,cnt)) return true;
        }
       return false;
    }
    
    int main () {
        while (cin>>n) {
            if (n==0) break;
            MT (vex,0);
            rep (i,1,n)
             rep (j,1,n) cin>>g[i][j];
            vex[n]=ans=1;
            per (i,n-1,0) {
                tot=0;
                rep (j,i+1,n) {
                    if (g[i][j]) temp[1][++tot]=j;
                }
                dfs (1,tot);
                vex[i]=ans;
            }
            cout<<ans<<endl;
        }
       
        return 0;
    }
    
  • 相关阅读:
    Windows系统中监控文件复制操作的几种方式
    右击菜单一键优化(增加新建office2003、新建reg和bat,删除新建公文包、新建wps、新建rar)
    美颜我迪!
    为什么我们不要 .NET 程序员
    访问局域网电脑提示“指定的网络名不存在”的解决办法
    WIN7X64SP1极限精简版by双心
    一键精简Windows不常用的字体.cmd
    dll文件32位64位检测工具以及Windows文件夹SysWow64的坑【转发】
    Win7精简成功后的总结
    dependency walker检查dll依赖关系目录设置的问题
  • 原文地址:https://www.cnblogs.com/hhlya/p/13396857.html
Copyright © 2011-2022 走看看